From 1ad8ee12b1d9666e6cf5db6bcb6e7e3ba5d5e40d Mon Sep 17 00:00:00 2001 From: swve Date: Mon, 10 Apr 2023 19:59:50 +0200 Subject: [PATCH 01/12] feat: init routes protection --- .../activity/[activityid]/edit/page.tsx | 2 +- .../(withmenu)/collections/new/page.tsx | 2 +- .../[orgslug]/(withmenu)/collections/page.tsx | 2 +- .../[courseid]/activity/[activityid]/page.tsx | 2 +- .../course/[courseid]/edit/page.tsx | 5 +-- .../(withmenu)/course/[courseid]/page.tsx | 21 ++++++---- .../[orgslug]/(withmenu)/courses/page.tsx | 2 +- .../_orgs/[orgslug]/(withmenu)/trail/page.tsx | 2 +- .../settings/organization/general/page.tsx | 2 +- front/app/organizations/page.tsx | 2 +- front/services/blocks/Image/images.ts | 2 +- front/services/blocks/Pdf/pdf.ts | 2 +- front/services/blocks/Quiz/quiz.ts | 2 +- front/services/blocks/Video/video.ts | 2 +- front/services/courses/activities.ts | 2 +- front/services/courses/activity.ts | 2 +- front/services/courses/chapters.ts | 39 +++++++------------ front/services/courses/collections.ts | 2 +- front/services/courses/courses.ts | 2 +- front/services/organizations/orgs.ts | 2 +- front/services/settings/org.ts | 2 +- front/services/settings/password.ts | 2 +- front/services/settings/profile.ts | 2 +- .../services/utils/react/middlewares/views.ts | 14 +++++++ front/services/utils/{ => ts}/requests.ts | 27 +++++++++---- 25 files changed, 82 insertions(+), 64 deletions(-) create mode 100644 front/services/utils/react/middlewares/views.ts rename front/services/utils/{ => ts}/requests.ts (61%) diff --git a/front/app/_editor/course/[courseid]/activity/[activityid]/edit/page.tsx b/front/app/_editor/course/[courseid]/activity/[activityid]/edit/page.tsx index 778ec4f0..6539e6c6 100644 --- a/front/app/_editor/course/[courseid]/activity/[activityid]/edit/page.tsx +++ b/front/app/_editor/course/[courseid]/activity/[activityid]/edit/page.tsx @@ -9,7 +9,7 @@ import AuthProvider from "@components/Security/AuthProvider"; import EditorWrapper from "@components/Editor/EditorWrapper"; import useSWR, { mutate } from "swr"; import { getAPIUrl } from "@services/config/config"; -import { swrFetcher } from "@services/utils/requests"; +import { swrFetcher } from "@services/utils/ts/requests"; function EditActivity(params: any) { diff --git a/front/app/_orgs/[orgslug]/(withmenu)/collections/new/page.tsx b/front/app/_orgs/[orgslug]/(withmenu)/collections/new/page.tsx index da1f8355..5a190dec 100644 --- a/front/app/_orgs/[orgslug]/(withmenu)/collections/new/page.tsx +++ b/front/app/_orgs/[orgslug]/(withmenu)/collections/new/page.tsx @@ -5,7 +5,7 @@ import { Title } from "@components/UI/Elements/Styles/Title"; import { createCollection } from "@services/courses/collections"; import useSWR from "swr"; import { getAPIUrl } from "@services/config/config"; -import { swrFetcher } from "@services/utils/requests"; +import { swrFetcher } from "@services/utils/ts/requests"; import { getOrganizationContextInfo } from "@services/organizations/orgs"; function NewCollection(params : any) { diff --git a/front/app/_orgs/[orgslug]/(withmenu)/collections/page.tsx b/front/app/_orgs/[orgslug]/(withmenu)/collections/page.tsx index c74dd467..a6169647 100644 --- a/front/app/_orgs/[orgslug]/(withmenu)/collections/page.tsx +++ b/front/app/_orgs/[orgslug]/(withmenu)/collections/page.tsx @@ -5,7 +5,7 @@ import styled from "styled-components"; import { Title } from "@components/UI/Elements/Styles/Title"; import { deleteCollection } from "@services/courses/collections"; import { getAPIUrl, getBackendUrl, getUriWithOrg } from "@services/config/config"; -import { swrFetcher } from "@services/utils/requests"; +import { swrFetcher } from "@services/utils/ts/requests"; import useSWR, { mutate } from "swr"; function Collections(params: any) { diff --git a/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/page.tsx b/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/page.tsx index 480040f2..b8d2d2b2 100644 --- a/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/page.tsx +++ b/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/page.tsx @@ -10,7 +10,7 @@ import { getCourse } from "@services/courses/courses"; import VideoActivity from "@components/Pages/Activities/Video/Video"; import useSWR, { mutate } from "swr"; import { Check } from "lucide-react"; -import { swrFetcher } from "@services/utils/requests"; +import { swrFetcher } from "@services/utils/ts/requests"; import { markActivityAsComplete } from "@services/courses/activity"; function ActivityPage(params: any) { diff --git a/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/edit/page.tsx b/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/edit/page.tsx index 45f0d10f..f2bd7c06 100644 --- a/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/edit/page.tsx +++ b/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/edit/page.tsx @@ -15,6 +15,7 @@ import { createActivity, createFileActivity } from "@services/courses/activities import { getOrganizationContextInfo } from "@services/organizations/orgs"; import Modal from "@components/UI/Modal/Modal"; import AuthProvider from "@components/Security/AuthProvider"; +import { denyAccessToUser } from "@services/utils/react/middlewares/views"; function CourseEdit(params: any) { @@ -38,9 +39,7 @@ function CourseEdit(params: any) { const courseChapters = await getCourseChaptersMetadata(courseid); setData(courseChapters); } catch (error: any) { - if (error.status === 401) { - router.push("/login"); - } + denyAccessToUser(error, router) } } diff --git a/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/page.tsx b/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/page.tsx index 0f2f3b4c..f098e2b6 100644 --- a/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/page.tsx +++ b/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/page.tsx @@ -1,21 +1,26 @@ "use client"; import { EyeOpenIcon, Pencil2Icon } from "@radix-ui/react-icons"; -import { removeCourse, startCourse } from "@services/courses/activity"; +import { removeCourse, startCourse } from "@services/courses/activity"; import Link from "next/link"; import React from "react"; import styled from "styled-components"; import { getAPIUrl, getBackendUrl, getUriWithOrg } from "@services/config/config"; import useSWR, { mutate } from "swr"; -import { swrFetcher } from "@services/utils/requests"; +import { swrFetcher } from "@services/utils/ts/requests"; +import { useRouter } from "next/navigation"; const CourseIdPage = (params: any) => { const courseid = params.params.courseid; const orgslug = params.params.orgslug; - const { data: course, error: error } = useSWR(`${getAPIUrl()}courses/meta/course_${courseid}`, swrFetcher); + const router = useRouter(); + + const { data: course, error: error } = useSWR(`${getAPIUrl()}courses/meta/course_${courseid}`, + (url: string, body: any) => swrFetcher(url, body, router) + ); async function startCourseUI() { // Create activity - await startCourse("course_" + courseid, orgslug); + await startCourse("course_" + courseid, orgslug); // Mutate course mutate(`${getAPIUrl()}courses/meta/course_${courseid}`); @@ -24,7 +29,7 @@ const CourseIdPage = (params: any) => { async function quitCourse() { // Close activity - let activity = await removeCourse("course_" + courseid, orgslug); + let activity = await removeCourse("course_" + courseid, orgslug); console.log(activity); // Mutate course @@ -42,7 +47,7 @@ const CourseIdPage = (params: any) => {

Course

{course.course.name}{" "} - + {" "}

@@ -53,7 +58,7 @@ const CourseIdPage = (params: any) => { {chapter.activities.map((activity: any) => { return ( <> - + {" "} @@ -94,7 +99,7 @@ const CourseIdPage = (params: any) => { <>

Activity {activity.name} - + {" "}

diff --git a/front/app/_orgs/[orgslug]/(withmenu)/courses/page.tsx b/front/app/_orgs/[orgslug]/(withmenu)/courses/page.tsx index 86706ad1..d7bfa2cd 100644 --- a/front/app/_orgs/[orgslug]/(withmenu)/courses/page.tsx +++ b/front/app/_orgs/[orgslug]/(withmenu)/courses/page.tsx @@ -7,7 +7,7 @@ import { Title } from "@components/UI/Elements/Styles/Title"; import { getAPIUrl, getBackendUrl, getSelfHostedOption, getUriWithOrg } from "@services/config/config"; import { deleteCourseFromBackend } from "@services/courses/courses"; import useSWR, { mutate } from "swr"; -import { swrFetcher } from "@services/utils/requests"; +import { swrFetcher } from "@services/utils/ts/requests"; import { Edit2, Trash } from "lucide-react"; const CoursesIndexPage = (params: any) => { diff --git a/front/app/_orgs/[orgslug]/(withmenu)/trail/page.tsx b/front/app/_orgs/[orgslug]/(withmenu)/trail/page.tsx index 2d86dacb..f965dce1 100644 --- a/front/app/_orgs/[orgslug]/(withmenu)/trail/page.tsx +++ b/front/app/_orgs/[orgslug]/(withmenu)/trail/page.tsx @@ -1,6 +1,6 @@ "use client"; import { getAPIUrl, getBackendUrl } from "@services/config/config"; -import { swrFetcher } from "@services/utils/requests"; +import { swrFetcher } from "@services/utils/ts/requests"; import React from "react"; import { styled } from "styled-components"; import useSWR from "swr"; diff --git a/front/app/_orgs/[orgslug]/settings/organization/general/page.tsx b/front/app/_orgs/[orgslug]/settings/organization/general/page.tsx index 4ecd1249..048f4fc2 100644 --- a/front/app/_orgs/[orgslug]/settings/organization/general/page.tsx +++ b/front/app/_orgs/[orgslug]/settings/organization/general/page.tsx @@ -1,7 +1,7 @@ "use client"; import React from 'react' import useSWR, { mutate } from "swr"; -import { swrFetcher } from "@services/utils/requests"; +import { swrFetcher } from "@services/utils/ts/requests"; import { getAPIUrl } from '@services/config/config'; import { Field, Form, Formik } from 'formik'; import { updateOrganization } from '@services/settings/org'; diff --git a/front/app/organizations/page.tsx b/front/app/organizations/page.tsx index ba286b4c..312ec33b 100644 --- a/front/app/organizations/page.tsx +++ b/front/app/organizations/page.tsx @@ -4,7 +4,7 @@ import React from "react"; import { Title } from "../../components/UI/Elements/Styles/Title"; import { deleteOrganizationFromBackend } from "@services/organizations/orgs"; import useSWR, { mutate } from "swr"; -import { swrFetcher } from "@services/utils/requests"; +import { swrFetcher } from "@services/utils/ts/requests"; import { getAPIUrl, getUriWithOrg } from "@services/config/config"; import AuthProvider from "@components/Security/AuthProvider"; diff --git a/front/services/blocks/Image/images.ts b/front/services/blocks/Image/images.ts index bb93582b..0429b6dd 100644 --- a/front/services/blocks/Image/images.ts +++ b/front/services/blocks/Image/images.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody, RequestBodyForm } from "@services/utils/requests"; +import { RequestBody, RequestBodyForm } from "@services/utils/ts/requests"; export async function uploadNewImageFile(file: any, activity_id: string) { // Send file thumbnail as form data diff --git a/front/services/blocks/Pdf/pdf.ts b/front/services/blocks/Pdf/pdf.ts index 2bff8fbe..fc9b4e5e 100644 --- a/front/services/blocks/Pdf/pdf.ts +++ b/front/services/blocks/Pdf/pdf.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody, RequestBodyForm } from "@services/utils/requests"; +import { RequestBody, RequestBodyForm } from "@services/utils/ts/requests"; export async function uploadNewPDFFile(file: any, activity_id: string) { // Send file thumbnail as form data diff --git a/front/services/blocks/Quiz/quiz.ts b/front/services/blocks/Quiz/quiz.ts index 706bbf00..0adb85dd 100644 --- a/front/services/blocks/Quiz/quiz.ts +++ b/front/services/blocks/Quiz/quiz.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody, RequestBodyForm } from "@services/utils/requests"; +import { RequestBody, RequestBodyForm } from "@services/utils/ts/requests"; export async function submitQuizBlock(activity_id: string, data: any) { diff --git a/front/services/blocks/Video/video.ts b/front/services/blocks/Video/video.ts index a2c45388..bf7142b4 100644 --- a/front/services/blocks/Video/video.ts +++ b/front/services/blocks/Video/video.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody, RequestBodyForm } from "@services/utils/requests"; +import { RequestBody, RequestBodyForm } from "@services/utils/ts/requests"; export async function uploadNewVideoFile(file: any, activity_id: string) { // Send file thumbnail as form data diff --git a/front/services/courses/activities.ts b/front/services/courses/activities.ts index 9ee811d6..02d8726c 100644 --- a/front/services/courses/activities.ts +++ b/front/services/courses/activities.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody, RequestBodyForm } from "@services/utils/requests"; +import { RequestBody, RequestBodyForm } from "@services/utils/ts/requests"; export async function createActivity(data: any, chapter_id: any, org_id: any) { data.content = {}; diff --git a/front/services/courses/activity.ts b/front/services/courses/activity.ts index d2fcda94..cce7f84f 100644 --- a/front/services/courses/activity.ts +++ b/front/services/courses/activity.ts @@ -1,4 +1,4 @@ -import { RequestBody } from "@services/utils/requests"; +import { RequestBody } from "@services/utils/ts/requests"; import { getAPIUrl } from "@services/config/config"; /* diff --git a/front/services/courses/chapters.ts b/front/services/courses/chapters.ts index 8bdc85e2..ddf2c521 100644 --- a/front/services/courses/chapters.ts +++ b/front/services/courses/chapters.ts @@ -1,6 +1,5 @@ -import { initialData } from "../../components/Pages/CourseEdit/Draggables/data"; import { getAPIUrl } from "@services/config/config"; -import { RequestBody } from "@services/utils/requests"; +import { RequestBody, errorHandling } from "@services/utils/ts/requests"; /* This file includes only POST, PUT, DELETE requests @@ -9,38 +8,26 @@ import { RequestBody } from "@services/utils/requests"; //TODO : depreciate this function export async function getCourseChaptersMetadata(course_id: any) { - const response = await fetch(`${getAPIUrl()}chapters/meta/course_${course_id}`, RequestBody("GET", null)); - - if (!response.ok) { - const error: any = new Error(`Error ${response.status}: ${response.statusText}`, {}); - error.status = response.status; - throw error; - } - - const data = await response.json(); - return data; + const result = await fetch(`${getAPIUrl()}chapters/meta/course_${course_id}`, RequestBody("GET", null)); + const res = await errorHandling(result); + return res; } export async function updateChaptersMetadata(course_id: any, data: any) { - const result: any = await fetch(`${getAPIUrl()}chapters/meta/course_${course_id}`, RequestBody("PUT", data)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); - - return result; + const result: any = await fetch(`${getAPIUrl()}chapters/meta/course_${course_id}`, RequestBody("PUT", data)); + const res = await errorHandling(result); + return res; } export async function createChapter(data: any, course_id: any) { - const result: any = await fetch(`${getAPIUrl()}chapters/?course_id=course_${course_id}`, RequestBody("POST", data)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); + const result: any = await fetch(`${getAPIUrl()}chapters/?course_id=course_${course_id}`, RequestBody("POST", data)); + const res = await errorHandling(result); - return result; + return res; } export async function deleteChapter(coursechapter_id: any) { - const result: any = await fetch(`${getAPIUrl()}chapters/${coursechapter_id}`, RequestBody("DELETE", null)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); - - return result; + const result: any = await fetch(`${getAPIUrl()}chapters/${coursechapter_id}`, RequestBody("DELETE", null)); + const res = await errorHandling(result); + return res; } diff --git a/front/services/courses/collections.ts b/front/services/courses/collections.ts index 2f213f0b..7429f5a6 100644 --- a/front/services/courses/collections.ts +++ b/front/services/courses/collections.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "../config/config"; -import { RequestBody } from "../utils/requests"; +import { RequestBody } from "../utils/ts/requests"; /* This file includes only POST, PUT, DELETE requests diff --git a/front/services/courses/courses.ts b/front/services/courses/courses.ts index d7307e70..a0236419 100644 --- a/front/services/courses/courses.ts +++ b/front/services/courses/courses.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody, RequestBodyForm } from "@services/utils/requests"; +import { RequestBody, RequestBodyForm } from "@services/utils/ts/requests"; /* This file includes only POST, PUT, DELETE requests diff --git a/front/services/organizations/orgs.ts b/front/services/organizations/orgs.ts index ddd6fde4..eb648285 100644 --- a/front/services/organizations/orgs.ts +++ b/front/services/organizations/orgs.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody } from "../utils/requests"; +import { RequestBody } from "../utils/ts/requests"; /* This file includes only POST, PUT, DELETE requests diff --git a/front/services/settings/org.ts b/front/services/settings/org.ts index 10842ca2..4f225fce 100644 --- a/front/services/settings/org.ts +++ b/front/services/settings/org.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody } from "@services/utils/requests"; +import { RequestBody } from "@services/utils/ts/requests"; /* This file includes only POST, PUT, DELETE requests diff --git a/front/services/settings/password.ts b/front/services/settings/password.ts index b4c13bb3..9cd57b28 100644 --- a/front/services/settings/password.ts +++ b/front/services/settings/password.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody } from "@services/utils/requests"; +import { RequestBody } from "@services/utils/ts/requests"; /* This file includes only POST, PUT, DELETE requests diff --git a/front/services/settings/profile.ts b/front/services/settings/profile.ts index bb1a048a..b6322d65 100644 --- a/front/services/settings/profile.ts +++ b/front/services/settings/profile.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody } from "@services/utils/requests"; +import { RequestBody } from "@services/utils/ts/requests"; /* This file includes only POST, PUT, DELETE requests diff --git a/front/services/utils/react/middlewares/views.ts b/front/services/utils/react/middlewares/views.ts new file mode 100644 index 00000000..6ab82348 --- /dev/null +++ b/front/services/utils/react/middlewares/views.ts @@ -0,0 +1,14 @@ +import { AppRouterInstance } from "next/dist/shared/lib/app-router-context"; +import { NextRouter } from "next/router"; + +export const denyAccessToUser = (error : any, router: AppRouterInstance) => { + if (error.status === 401) { + router.push("/login"); + } + + if (error.status === 403) { + router.push("/login"); + // TODO : add a message to the user to tell him he is not allowed to access this page, route to /error + } + +} \ No newline at end of file diff --git a/front/services/utils/requests.ts b/front/services/utils/ts/requests.ts similarity index 61% rename from front/services/utils/requests.ts rename to front/services/utils/ts/requests.ts index 3f4e6466..ee372a47 100644 --- a/front/services/utils/requests.ts +++ b/front/services/utils/ts/requests.ts @@ -1,3 +1,6 @@ +import { AppRouterInstance } from "next/dist/shared/lib/app-router-context"; +import { denyAccessToUser } from "../react/middlewares/views"; + export const RequestBody = (method: string, data: any) => { let HeadersConfig = new Headers({ "Content-Type": "application/json" }); let options: any = { @@ -24,7 +27,7 @@ export const RequestBodyForm = (method: string, data: any) => { return options; }; -export const swrFetcher = async (url: string, body: any) => { +export const swrFetcher = async (url: string, body: any, router?: AppRouterInstance) => { // Create the request options let HeadersConfig = new Headers({ "Content-Type": "application/json" }); let options: any = { @@ -39,15 +42,25 @@ export const swrFetcher = async (url: string, body: any) => { options.body = JSON.stringify(body); } - // Fetch the data - const res = await fetch(url, options); + try { + // Fetch the data + const request = await fetch(url, options); + let res = errorHandling(request); - // If the response is not in the 200 range, throw an error + // Return the data + return res; + } catch (error: any) { + if (router) { + denyAccessToUser(error, router); + } + } +}; + +export const errorHandling = (res: any) => { if (!res.ok) { - const error = new Error("An error occurred while fetching the data."); + const error: any = new Error(`Error ${res.status}: ${res.statusText}`, {}); + error.status = res.status; throw error; } - - // Return the data return res.json(); }; From 186b0e840150a130f2c4141f9233ae0ba7ba372d Mon Sep 17 00:00:00 2001 From: swve Date: Mon, 10 Apr 2023 20:35:14 +0200 Subject: [PATCH 02/12] fix: better error handling across the app --- .../[courseid]/activity/[activityid]/page.tsx | 9 ++--- front/services/courses/activities.ts | 37 ++++++------------- front/services/courses/activity.ts | 17 ++++----- front/services/courses/collections.ts | 14 +++---- front/services/courses/courses.ts | 34 +++++++---------- front/services/organizations/orgs.ts | 20 +++++----- front/services/settings/org.ts | 12 +++--- front/services/settings/password.ts | 8 ++-- front/services/settings/profile.ts | 8 ++-- front/services/utils/ts/requests.ts | 1 + src/services/courses/courses.py | 2 +- 11 files changed, 66 insertions(+), 96 deletions(-) diff --git a/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/page.tsx b/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/page.tsx index b8d2d2b2..020c734d 100644 --- a/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/page.tsx +++ b/front/app/_orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/page.tsx @@ -19,7 +19,7 @@ function ActivityPage(params: any) { const orgslug = params.params.orgslug; const { data: course, error: error_course } = useSWR(`${getAPIUrl()}courses/meta/course_${courseid}`, swrFetcher); - const { data: activity, error: error_activity } = useSWR(`${getAPIUrl()}trail/org_slug/${orgslug}/trail`, swrFetcher); + const { data: activity, error: error_activity } = useSWR(`${getAPIUrl()}activities/activity_${activityid}`, swrFetcher); async function markActivityAsCompleteFront() { @@ -31,7 +31,7 @@ function ActivityPage(params: any) { return ( <> {error_course &&

Failed to load

} - {!course || !activity ? ( + {!course && !activity ? (
Loading...
) : ( @@ -95,9 +95,8 @@ function ActivityPage(params: any) { )} - ) : ( -
Loading...
- )} + ) : (
)} + {error_activity &&

Failed to load {error_activity.message}

}
)} diff --git a/front/services/courses/activities.ts b/front/services/courses/activities.ts index 02d8726c..fa378281 100644 --- a/front/services/courses/activities.ts +++ b/front/services/courses/activities.ts @@ -5,15 +5,10 @@ export async function createActivity(data: any, chapter_id: any, org_id: any) { data.content = {}; // remove chapter_id from data delete data.chapterId; - - const result: any = await fetch(`${getAPIUrl()}activities/?coursechapter_id=${chapter_id}&org_id=${org_id}`, RequestBody("POST", data)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); - - console.log("result", result); - - return result; + const result = await fetch(`${getAPIUrl()}activities/?coursechapter_id=${chapter_id}&org_id=${org_id}`, RequestBody("POST", data)); + const res = await result.json(); + return res; } export async function createFileActivity(file: File, type: string, data: any, chapter_id: any) { @@ -29,27 +24,19 @@ export async function createFileActivity(file: File, type: string, data: any, ch endpoint = `${getAPIUrl()}activities/video`; } - const result: any = await fetch(endpoint, RequestBodyForm("POST", formData)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); - - console.log("result", result); - - return result; + const result: any = await fetch(endpoint, RequestBodyForm("POST", formData)); + const res = await result.json(); + return res; } export async function getActivity(activity_id: any) { - const result: any = await fetch(`${getAPIUrl()}activities/${activity_id}`, RequestBody("GET", null)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); - - return result; + const result = await fetch(`${getAPIUrl()}activities/${activity_id}`, RequestBody("GET", null)); + const res = await result.json(); + return res; } export async function updateActivity(data: any, activity_id: any) { - const result: any = await fetch(`${getAPIUrl()}activities/${activity_id}`, RequestBody("PUT", data)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); - - return result; + const result = await fetch(`${getAPIUrl()}activities/${activity_id}`, RequestBody("PUT", data)); + const res = await result.json(); + return res; } diff --git a/front/services/courses/activity.ts b/front/services/courses/activity.ts index cce7f84f..aec4ec45 100644 --- a/front/services/courses/activity.ts +++ b/front/services/courses/activity.ts @@ -1,4 +1,4 @@ -import { RequestBody } from "@services/utils/ts/requests"; +import { RequestBody, errorHandling } from "@services/utils/ts/requests"; import { getAPIUrl } from "@services/config/config"; /* @@ -8,21 +8,18 @@ import { getAPIUrl } from "@services/config/config"; export async function startCourse(course_id: string, org_slug: string) { const result: any = await fetch(`${getAPIUrl()}trail/org_slug/${org_slug}/add_course/${course_id}`, RequestBody("POST", null)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); - return result; + const res = await errorHandling(result); + return res; } export async function removeCourse(course_id: string, org_slug: string) { const result: any = await fetch(`${getAPIUrl()}trail/org_slug/${org_slug}/remove_course/${course_id}`, RequestBody("POST", null)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); - return result; + const res = await errorHandling(result); + return res; } export async function markActivityAsComplete(org_slug: string, course_id: string, activity_id: string) { const result: any = await fetch(`${getAPIUrl()}trail/org_slug/${org_slug}/add_activity/course_id/${course_id}/activity_id/${activity_id}`, RequestBody("POST", null)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); - return result; + const res = await errorHandling(result); + return res; } diff --git a/front/services/courses/collections.ts b/front/services/courses/collections.ts index 7429f5a6..09ca1610 100644 --- a/front/services/courses/collections.ts +++ b/front/services/courses/collections.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "../config/config"; -import { RequestBody } from "../utils/ts/requests"; +import { RequestBody, errorHandling } from "@services/utils/ts/requests"; /* This file includes only POST, PUT, DELETE requests @@ -7,14 +7,14 @@ import { RequestBody } from "../utils/ts/requests"; */ export async function deleteCollection(collection_id: any) { - return fetch(`${getAPIUrl()}collections/${collection_id}`, RequestBody("DELETE", null)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); + const result: any = await fetch(`${getAPIUrl()}collections/${collection_id}`, RequestBody("DELETE", null)); + const res = await errorHandling(result); + return res; } // Create a new collection export async function createCollection(collection: any) { - return fetch(`${getAPIUrl()}collections/`, RequestBody("POST", collection)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); + const result: any = await fetch(`${getAPIUrl()}collections/`, RequestBody("POST", collection)); + const res = await errorHandling(result); + return res; } diff --git a/front/services/courses/courses.ts b/front/services/courses/courses.ts index a0236419..13486429 100644 --- a/front/services/courses/courses.ts +++ b/front/services/courses/courses.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody, RequestBodyForm } from "@services/utils/ts/requests"; +import { RequestBody, RequestBodyForm, errorHandling } from "@services/utils/ts/requests"; /* This file includes only POST, PUT, DELETE requests @@ -7,23 +7,18 @@ import { RequestBody, RequestBodyForm } from "@services/utils/ts/requests"; */ export async function getOrgCourses(org_id: number) { - - - return fetch(`${getAPIUrl()}courses/${org_id}/page/1/limit/10`, RequestBody("GET", null)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); + const result: any = await fetch(`${getAPIUrl()}courses/${org_id}/page/1/limit/10`, RequestBody("GET", null)); + const res = await errorHandling(result); + return res; } export async function getCourse(course_id: string) { - // todo : add course id to url - return fetch(`${getAPIUrl()}courses/${course_id}`, RequestBody("GET", null)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); + const result: any = await fetch(`${getAPIUrl()}courses/${course_id}`, RequestBody("GET", null)); + const res = await errorHandling(result); + return res; } - export async function createNewCourse(org_id: string, course_body: any, thumbnail: any) { - // Send file thumbnail as form data const formData = new FormData(); formData.append("thumbnail", thumbnail); @@ -32,16 +27,13 @@ export async function createNewCourse(org_id: string, course_body: any, thumbnai formData.append("mini_description", "course_body.mini_description"); formData.append("public", "true"); - - return fetch(`${getAPIUrl()}courses/?org_id=${org_id}`, RequestBodyForm("POST", formData)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); + const result = await fetch(`${getAPIUrl()}courses/?org_id=${org_id}`, RequestBodyForm("POST", formData)); + const res = await errorHandling(result); + return res; } export async function deleteCourseFromBackend(course_id: any) { - - - return fetch(`${getAPIUrl()}courses/${course_id}`, RequestBody("DELETE", null)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); + const result: any = await fetch(`${getAPIUrl()}courses/${course_id}`, RequestBody("DELETE", null)); + const res = await errorHandling(result); + return res; } diff --git a/front/services/organizations/orgs.ts b/front/services/organizations/orgs.ts index eb648285..2718df70 100644 --- a/front/services/organizations/orgs.ts +++ b/front/services/organizations/orgs.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody } from "../utils/ts/requests"; +import { RequestBody, errorHandling } from "@services/utils/ts/requests"; /* This file includes only POST, PUT, DELETE requests @@ -7,19 +7,19 @@ import { RequestBody } from "../utils/ts/requests"; */ export async function createNewOrganization(body: any) { - return fetch(`${getAPIUrl()}orgs/`, RequestBody("POST", body)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); + const result = await fetch(`${getAPIUrl()}orgs/`, RequestBody("POST", body)); + const res = await errorHandling(result); + return res; } export async function deleteOrganizationFromBackend(org_id: any) { - return fetch(`${getAPIUrl()}orgs/${org_id}`, RequestBody("DELETE", null)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); + const result = await fetch(`${getAPIUrl()}orgs/${org_id}`, RequestBody("DELETE", null)); + const res = await errorHandling(result); + return res; } export async function getOrganizationContextInfo(org_slug: any) { - return fetch(`${getAPIUrl()}orgs/slug/${org_slug}`, RequestBody("GET", null)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); + const result = await fetch(`${getAPIUrl()}orgs/slug/${org_slug}`, RequestBody("GET", null)); + const res = await errorHandling(result); + return res; } diff --git a/front/services/settings/org.ts b/front/services/settings/org.ts index 4f225fce..1f4a0fd8 100644 --- a/front/services/settings/org.ts +++ b/front/services/settings/org.ts @@ -1,15 +1,13 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody } from "@services/utils/ts/requests"; +import { RequestBody, errorHandling } from "@services/utils/ts/requests"; /* This file includes only POST, PUT, DELETE requests GET requests are called from the frontend using SWR (https://swr.vercel.app/) */ -export async function updateOrganization(org_id : string, data: any) { - const result: any = await fetch(`${getAPIUrl()}orgs/` + org_id, RequestBody("PUT", data)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); - - return result; +export async function updateOrganization(org_id: string, data: any) { + const result: any = await fetch(`${getAPIUrl()}orgs/` + org_id, RequestBody("PUT", data)); + const res = await errorHandling(result); + return res; } diff --git a/front/services/settings/password.ts b/front/services/settings/password.ts index 9cd57b28..a93483f3 100644 --- a/front/services/settings/password.ts +++ b/front/services/settings/password.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody } from "@services/utils/ts/requests"; +import { RequestBody, errorHandling } from "@services/utils/ts/requests"; /* This file includes only POST, PUT, DELETE requests @@ -8,8 +8,6 @@ import { RequestBody } from "@services/utils/ts/requests"; export async function updatePassword(user_id : string, data: any) { const result: any = await fetch(`${getAPIUrl()}users/password/user_id/` + user_id, RequestBody("PUT", data)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); - - return result; + const res = await errorHandling(result); + return res; } diff --git a/front/services/settings/profile.ts b/front/services/settings/profile.ts index b6322d65..06f0667e 100644 --- a/front/services/settings/profile.ts +++ b/front/services/settings/profile.ts @@ -1,5 +1,5 @@ import { getAPIUrl } from "@services/config/config"; -import { RequestBody } from "@services/utils/ts/requests"; +import { RequestBody, errorHandling } from "@services/utils/ts/requests"; /* This file includes only POST, PUT, DELETE requests @@ -8,8 +8,6 @@ import { RequestBody } from "@services/utils/ts/requests"; export async function updateProfile(data: any) { const result: any = await fetch(`${getAPIUrl()}users/user_id/` + data.user_id, RequestBody("PUT", data)) - .then((result) => result.json()) - .catch((error) => console.log("error", error)); - - return result; + const res = await errorHandling(result); + return res; } diff --git a/front/services/utils/ts/requests.ts b/front/services/utils/ts/requests.ts index ee372a47..802f92ec 100644 --- a/front/services/utils/ts/requests.ts +++ b/front/services/utils/ts/requests.ts @@ -53,6 +53,7 @@ export const swrFetcher = async (url: string, body: any, router?: AppRouterInsta if (router) { denyAccessToUser(error, router); } + throw error; } }; diff --git a/src/services/courses/courses.py b/src/services/courses/courses.py index d8dee31a..55b12d67 100644 --- a/src/services/courses/courses.py +++ b/src/services/courses/courses.py @@ -288,7 +288,7 @@ async def verify_rights(request: Request, course_id: str, current_user: PublicUs course = await courses.find_one({"course_id": course_id}) - if current_user.user_id == "anonymous" and course["public"] == True: + if current_user.user_id == "anonymous" and course["public"] == True and action == "read": return True if not course: From 7869b6fd7f53758e4ae2388c2b6ca534d6d1fbd6 Mon Sep 17 00:00:00 2001 From: swve Date: Tue, 11 Apr 2023 23:13:32 +0200 Subject: [PATCH 03/12] feat: use env variables for backend values --- front/services/config/config.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/front/services/config/config.ts b/front/services/config/config.ts index 8e9a63a6..401b7000 100644 --- a/front/services/config/config.ts +++ b/front/services/config/config.ts @@ -1,5 +1,7 @@ -const LEARNHOUSE_API_URL = "http://localhost:1338/api/"; -const LEARNHOUSE_BACKEND_URL = "http://localhost:1338/"; +const LEARNHOUSE_HTTP_PROTOCOL = process.env.NEXT_PUBLIC_LEARNHOUSE_HTTPS === "true" ? "https://" : "http://"; +const LEARNHOUSE_API_URL = `${process.env.NEXT_PUBLIC_LEARNHOUSE_API_URL}`; +const LEARNHOUSE_BACKEND_URL = `${process.env.NEXT_PUBLIC_LEARNHOUSE_BACKEND_URL}`; +const LEARNHOUSE_DOMAIN = process.env.NEXT_PUBLIC_LEARNHOUSE_DOMAIN; export const getAPIUrl = () => LEARNHOUSE_API_URL; export const getBackendUrl = () => LEARNHOUSE_BACKEND_URL; @@ -7,11 +9,10 @@ export const getSelfHostedOption = () => (process.env.NEXT_PUBLIC_LEARNHOUSE_SEL export const getUriWithOrg = (orgslug: string, path: string) => { const selfHosted = getSelfHostedOption(); - if (selfHosted) { - return `http://localhost:3000${path}`; + return `${LEARNHOUSE_DOMAIN}${path}`; } - return `http://${orgslug}.localhost:3000${path}`; + return `${LEARNHOUSE_HTTP_PROTOCOL}${orgslug}.${LEARNHOUSE_DOMAIN}${path}`; }; export const getOrgFromUri = () => { @@ -21,8 +22,8 @@ export const getOrgFromUri = () => { } else { if (typeof window !== "undefined") { const hostname = window.location.hostname; - - return hostname.replace(".localhost", ""); + + return hostname.replace(`.${LEARNHOUSE_DOMAIN}`, ""); } } }; From bb555fc3e03a5ac65c79ca660d620d135dee644f Mon Sep 17 00:00:00 2001 From: swve Date: Tue, 11 Apr 2023 23:31:17 +0200 Subject: [PATCH 04/12] fix: support edge runtime --- front/middleware.ts | 4 ++-- front/services/config/config.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/front/middleware.ts b/front/middleware.ts index 56fd95cd..f78c3cf4 100644 --- a/front/middleware.ts +++ b/front/middleware.ts @@ -1,4 +1,4 @@ -import { getDefaultOrg, getSelfHostedOption } from "@services/config/config"; +import { LEARNHOUSE_DOMAIN, getDefaultOrg, getSelfHostedOption } from "./services/config/config"; import { NextRequest, NextResponse } from "next/server"; export const config = { @@ -19,7 +19,7 @@ export default function middleware(req: NextRequest) { const url = req.nextUrl; const isSelfHosted = getSelfHostedOption(); const hostname = req.headers.get("host") || "learnhouse.app"; - let currentHost = hostname.replace(".localhost:3000", ""); + let currentHost = hostname.replace(`.${LEARNHOUSE_DOMAIN}`, ""); if (!isSelfHosted && currentHost === "localhost:3000" && !url.pathname.startsWith("/organizations")) { // Redirect to error page if not self-hosted and on localhost diff --git a/front/services/config/config.ts b/front/services/config/config.ts index 401b7000..ed5ee7e4 100644 --- a/front/services/config/config.ts +++ b/front/services/config/config.ts @@ -1,7 +1,7 @@ const LEARNHOUSE_HTTP_PROTOCOL = process.env.NEXT_PUBLIC_LEARNHOUSE_HTTPS === "true" ? "https://" : "http://"; const LEARNHOUSE_API_URL = `${process.env.NEXT_PUBLIC_LEARNHOUSE_API_URL}`; const LEARNHOUSE_BACKEND_URL = `${process.env.NEXT_PUBLIC_LEARNHOUSE_BACKEND_URL}`; -const LEARNHOUSE_DOMAIN = process.env.NEXT_PUBLIC_LEARNHOUSE_DOMAIN; +export const LEARNHOUSE_DOMAIN = process.env.NEXT_PUBLIC_LEARNHOUSE_DOMAIN; export const getAPIUrl = () => LEARNHOUSE_API_URL; export const getBackendUrl = () => LEARNHOUSE_BACKEND_URL; From ea0b1ea0149f2cc902c5d86e5146288cce8e2739 Mon Sep 17 00:00:00 2001 From: Badr B Date: Wed, 12 Apr 2023 11:55:10 +0200 Subject: [PATCH 05/12] chore: move to next 13.2.4 --- front/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/package.json b/front/package.json index eea65ed2..fe1bceca 100644 --- a/front/package.json +++ b/front/package.json @@ -24,7 +24,7 @@ "formik": "^2.2.9", "framer-motion": "^7.3.6", "lucide-react": "^0.104.1", - "next": "^13.2.0", + "next": "^13.2.4", "react": "^18.2.0", "react-beautiful-dnd": "^13.1.1", "react-dom": "^18.2.0", From 6e3f908af5aa6d6b80604c6fa0a97c714d1dbb8f Mon Sep 17 00:00:00 2001 From: Badr B Date: Wed, 12 Apr 2023 12:42:48 +0200 Subject: [PATCH 06/12] fix: less imports in middleware --- front/middleware.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/front/middleware.ts b/front/middleware.ts index f78c3cf4..c4071df0 100644 --- a/front/middleware.ts +++ b/front/middleware.ts @@ -1,4 +1,4 @@ -import { LEARNHOUSE_DOMAIN, getDefaultOrg, getSelfHostedOption } from "./services/config/config"; + import { NextRequest, NextResponse } from "next/server"; export const config = { @@ -15,13 +15,16 @@ export const config = { ], }; + export default function middleware(req: NextRequest) { + const LEARNHOUSE_DOMAIN = process.env.NEXT_PUBLIC_LEARNHOUSE_DOMAIN; const url = req.nextUrl; - const isSelfHosted = getSelfHostedOption(); + const isSelfHosted = process.env.NEXT_PUBLIC_LEARNHOUSE_SELF_HOSTED === "true" ? true : false const hostname = req.headers.get("host") || "learnhouse.app"; + const defaultOrg = isSelfHosted ? process.env.NEXT_PUBLIC_LEARNHOUSE_DEFAULT_ORG : null; let currentHost = hostname.replace(`.${LEARNHOUSE_DOMAIN}`, ""); - if (!isSelfHosted && currentHost === "localhost:3000" && !url.pathname.startsWith("/organizations")) { + if (!isSelfHosted && currentHost === LEARNHOUSE_DOMAIN && !url.pathname.startsWith("/organizations")) { // Redirect to error page if not self-hosted and on localhost const errorUrl = "/error"; return NextResponse.redirect(errorUrl, { status: 302 }); From ef5fcd587002c5d1788e8b0cd614834275d631f3 Mon Sep 17 00:00:00 2001 From: Badr B Date: Wed, 12 Apr 2023 12:44:13 +0200 Subject: [PATCH 07/12] fix : typo --- front/middleware.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/middleware.ts b/front/middleware.ts index c4071df0..baeb1761 100644 --- a/front/middleware.ts +++ b/front/middleware.ts @@ -45,7 +45,7 @@ export default function middleware(req: NextRequest) { } if (isSelfHosted) { - currentHost = getDefaultOrg() || currentHost; + currentHost = defaultOrg || currentHost; } url.pathname = `/_orgs/${currentHost}${url.pathname}`; From 8cc6111aaf4fea19971a27159d5cff96144fceee Mon Sep 17 00:00:00 2001 From: swve Date: Wed, 12 Apr 2023 22:24:17 +0200 Subject: [PATCH 08/12] feat: use env variables to load db --- config/config.py | 9 ++++++++- config/config.yaml | 1 + src/core/events/database.py | 13 ++++++++----- src/core/events/events.py | 5 +++++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/config/config.py b/config/config.py index e94ae341..afe0a99a 100644 --- a/config/config.py +++ b/config/config.py @@ -1,3 +1,4 @@ +from typing import Optional from pydantic import BaseModel import os import yaml @@ -19,6 +20,7 @@ class DatabaseConfig(BaseModel): user: str password: str database_name: str + mongodb_connection_string: Optional[str] class LearnHouseConfig(BaseModel): @@ -54,6 +56,8 @@ def get_learnhouse_config() -> LearnHouseConfig: env_user = os.environ.get('LEARNHOUSE_DB_USER') env_password = os.environ.get('LEARNHOUSE_DB_PASSWORD') env_database_name = os.environ.get('LEARNHOUSE_DB_NAME') + env_mongodb_connection_string = os.environ.get( + 'LEARNHOUSE_MONGODB_CONNECTION_STRING') # Fill in values with YAML file if they are not provided site_name = env_site_name or yaml_config.get('site_name') @@ -80,6 +84,8 @@ def get_learnhouse_config() -> LearnHouseConfig: 'database_config', {}).get('password') database_name = env_database_name or yaml_config.get( 'database_config', {}).get('database_name') + mongodb_connection_string = env_mongodb_connection_string or yaml_config.get( + 'database_config', {}).get('mongodb_connection_string') # Create HostingConfig and DatabaseConfig objects hosting_config = HostingConfig( @@ -96,7 +102,8 @@ def get_learnhouse_config() -> LearnHouseConfig: port=int(db_port), user=user, password=password, - database_name=database_name + database_name=database_name, + mongodb_connection_string=mongodb_connection_string ) # Create LearnHouseConfig object diff --git a/config/config.yaml b/config/config.yaml index 65532180..d813e5e2 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -20,3 +20,4 @@ database_config: user: myuser password: mypassword database_name: mydatabase + mongodb_connection_string: mongodb://learnhouse:learnhouse@mongo:27017/ diff --git a/src/core/events/database.py b/src/core/events/database.py index 56913242..174575a6 100644 --- a/src/core/events/database.py +++ b/src/core/events/database.py @@ -2,17 +2,20 @@ import logging from fastapi import FastAPI import motor.motor_asyncio -async def connect_to_db(app: FastAPI) : + +async def connect_to_db(app: FastAPI): logging.info("Connecting to database...") try: - app.mongodb_client = motor.motor_asyncio.AsyncIOMotorClient("mongodb://learnhouse:learnhouse@mongo:27017/") # type: ignore - app.db = app.mongodb_client["learnhouse"] # type: ignore + app.mongodb_client = motor.motor_asyncio.AsyncIOMotorClient( # type: ignore + app.learnhouse_config.database_config.mongodb_connection_string) # type: ignore + app.db = app.mongodb_client["learnhouse"] # type: ignore logging.info("Connected to database!") except Exception as e: logging.error("Failed to connect to database!") logging.error(e) + async def close_database(app: FastAPI): - app.mongodb_client.close() # type: ignore + app.mongodb_client.close() # type: ignore logging.info("LearnHouse has been shut down.") - return app \ No newline at end of file + return app diff --git a/src/core/events/events.py b/src/core/events/events.py index 27dd830b..0830d3f5 100644 --- a/src/core/events/events.py +++ b/src/core/events/events.py @@ -1,11 +1,16 @@ from typing import Callable from fastapi import FastAPI +from config.config import LearnHouseConfig, get_learnhouse_config from src.core.events.database import close_database, connect_to_db from src.core.events.logs import create_logs_dir def startup_app(app: FastAPI) -> Callable: async def start_app() -> None: + # Get LearnHouse Config + learnhouse_config: LearnHouseConfig = get_learnhouse_config() + app.learnhouse_config = learnhouse_config # type: ignore + # Connect to database await connect_to_db(app) From 9c459c6ff0078c437176f9af2830696fc700f354 Mon Sep 17 00:00:00 2001 From: swve Date: Wed, 12 Apr 2023 22:46:23 +0200 Subject: [PATCH 09/12] fix: mock folder imgs --- app.py | 2 +- {config => src/core/config}/config.py | 0 src/core/events/events.py | 4 ++-- src/services/mocks/initial.py | 6 ++++++ 4 files changed, 9 insertions(+), 3 deletions(-) rename {config => src/core/config}/config.py (100%) diff --git a/app.py b/app.py index d3a99f8b..ba63f890 100644 --- a/app.py +++ b/app.py @@ -2,7 +2,7 @@ import asyncio import logging from fastapi import FastAPI, Request import re -from config.config import LearnHouseConfig, get_learnhouse_config +from src.core.config.config import LearnHouseConfig, get_learnhouse_config from src.core.events.events import shutdown_app, startup_app from src.main import global_router from fastapi.middleware.cors import CORSMiddleware diff --git a/config/config.py b/src/core/config/config.py similarity index 100% rename from config/config.py rename to src/core/config/config.py diff --git a/src/core/events/events.py b/src/core/events/events.py index 0830d3f5..4e64db3e 100644 --- a/src/core/events/events.py +++ b/src/core/events/events.py @@ -1,6 +1,6 @@ from typing import Callable from fastapi import FastAPI -from config.config import LearnHouseConfig, get_learnhouse_config +from src.core.config.config import LearnHouseConfig, get_learnhouse_config from src.core.events.database import close_database, connect_to_db from src.core.events.logs import create_logs_dir @@ -10,7 +10,7 @@ def startup_app(app: FastAPI) -> Callable: # Get LearnHouse Config learnhouse_config: LearnHouseConfig = get_learnhouse_config() app.learnhouse_config = learnhouse_config # type: ignore - + # Connect to database await connect_to_db(app) diff --git a/src/services/mocks/initial.py b/src/services/mocks/initial.py index a4e206ca..c7f4cbf8 100644 --- a/src/services/mocks/initial.py +++ b/src/services/mocks/initial.py @@ -1,3 +1,4 @@ +import os import requests from datetime import datetime from fileinput import filename @@ -184,6 +185,11 @@ async def create_initial_data(request: Request): image = requests.get( "https://source.unsplash.com/random/800x600") + + # check if folder exists and create it if not + if not os.path.exists("content/uploads/img"): + os.makedirs("content/uploads/img") + with open(f"content/uploads/img/{name_in_disk}", "wb") as f: f.write(image.content) From 6bd36cdc18186f9751ad4a11e6d069bc4642b8da Mon Sep 17 00:00:00 2001 From: swve Date: Wed, 12 Apr 2023 22:51:55 +0200 Subject: [PATCH 10/12] chore: refactor --- {src/core/config => config}/config.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {src/core/config => config}/config.py (100%) diff --git a/src/core/config/config.py b/config/config.py similarity index 100% rename from src/core/config/config.py rename to config/config.py From 71129bf510ac4a0f46a84110356d9ca60fdc2902 Mon Sep 17 00:00:00 2001 From: swve Date: Wed, 12 Apr 2023 22:55:29 +0200 Subject: [PATCH 11/12] fix: more import issues --- app.py | 2 +- src/core/events/events.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app.py b/app.py index ba63f890..d3a99f8b 100644 --- a/app.py +++ b/app.py @@ -2,7 +2,7 @@ import asyncio import logging from fastapi import FastAPI, Request import re -from src.core.config.config import LearnHouseConfig, get_learnhouse_config +from config.config import LearnHouseConfig, get_learnhouse_config from src.core.events.events import shutdown_app, startup_app from src.main import global_router from fastapi.middleware.cors import CORSMiddleware diff --git a/src/core/events/events.py b/src/core/events/events.py index 4e64db3e..c7afb00f 100644 --- a/src/core/events/events.py +++ b/src/core/events/events.py @@ -1,6 +1,6 @@ from typing import Callable from fastapi import FastAPI -from src.core.config.config import LearnHouseConfig, get_learnhouse_config +from config.config import LearnHouseConfig, get_learnhouse_config from src.core.events.database import close_database, connect_to_db from src.core.events.logs import create_logs_dir From a33a17803d95970d3a5212ec4b9337f6b99caff1 Mon Sep 17 00:00:00 2001 From: swve Date: Wed, 12 Apr 2023 23:13:50 +0200 Subject: [PATCH 12/12] fix: mock images issue --- content/uploads/__init__.py | 0 src/services/mocks/initial.py | 7 ++++--- 2 files changed, 4 insertions(+), 3 deletions(-) delete mode 100644 content/uploads/__init__.py diff --git a/content/uploads/__init__.py b/content/uploads/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/src/services/mocks/initial.py b/src/services/mocks/initial.py index c7f4cbf8..ea443c1d 100644 --- a/src/services/mocks/initial.py +++ b/src/services/mocks/initial.py @@ -184,11 +184,12 @@ async def create_initial_data(request: Request): name_in_disk = f"test_mock{course_id}.jpeg" image = requests.get( - "https://source.unsplash.com/random/800x600") + "https://source.unsplash.com/random/800x600/?img=1") # check if folder exists and create it if not - if not os.path.exists("content/uploads/img"): - os.makedirs("content/uploads/img") + if not os.path.exists(f"content/uploads/img"): + + os.makedirs(f"content/uploads/img") with open(f"content/uploads/img/{name_in_disk}", "wb") as f: f.write(image.content)