Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Commit

Permalink
oops
Browse files Browse the repository at this point in the history
  • Loading branch information
JibrilExe committed Mar 31, 2024
1 parent 5ffca16 commit 1fc130b
Show file tree
Hide file tree
Showing 34 changed files with 4,301 additions and 0 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/ci-linter-backend.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: UGent-3-backend-linter
run-name: ${{ github.actor }} is running backend linter 🚀
on:
pull_request:
paths:
- 'backend/**'
jobs:
Backend-tests:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
cache: 'pip'

- name: Run linting
working-directory: ./backend
run: find . -type f -name "*.py" | xargs pylint

30 changes: 30 additions & 0 deletions .github/workflows/ci-linter-frontend.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: UGent-3-frontend-linter
run-name: ${{ github.actor }} is running frontend linter 🚀
on:
pull_request:
paths:
- 'frontend/**'
jobs:
Frontend-tests:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4

- name: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: npm-

- name: Install dependencies
working-directory: ./frontend
run: npm i eslint

- name: Run linting
working-directory: ./frontend
run: npm run lint

27 changes: 27 additions & 0 deletions .github/workflows/ci-test-backend.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: UGent-3-backend-test
run-name: ${{ github.actor }} is running backend tests 🚀
on:
pull_request:
paths:
- 'backend/**'
jobs:
Backend-tests:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
cache: 'pip'

- name: Install dependencies
working-directory: ./backend
run: pip3 install -r requirements.txt && pip3 install -r dev-requirements.txt

- name: Running tests
working-directory: ./backend
run: bash ./run_tests.sh


38 changes: 38 additions & 0 deletions .github/workflows/ci-test-frontend.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: UGent-3-frontend-test
run-name: ${{ github.actor }} is running frontend tests 🚀
on:
pull_request:
paths:
- 'frontend/**'
jobs:
Frontend-tests:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4

- name: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: npm-

- name: Install dependencies
working-directory: ./frontend
run: npm ci

- name: Build
working-directory: ./frontend
run: npm run build

- name: Preview Web App
working-directory: ./frontend
run: npm run preview &

- name: Running tests
working-directory: ./frontend
run: npm test

9 changes: 9 additions & 0 deletions backend/Dockerfile_auth_test
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM python:3.9
RUN mkdir /auth-app
WORKDIR /auth-app
ADD ./test_auth_server /auth-app/
COPY auth_requirements.txt /auth-app/requirements.txt
RUN pip3 install -r requirements.txt
COPY . /auth-app
ENTRYPOINT ["python"]
CMD ["__main__.py"]
4 changes: 4 additions & 0 deletions backend/auth_requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
flask~=3.0.2
flask-restful
python-dotenv~=1.0.1
psycopg2-binary
27 changes: 27 additions & 0 deletions backend/flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions backend/flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
description = "Python pip DevShell";

inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";

outputs = { self, nixpkgs }: let
systems = [ "x86_64-linux" ];
forAllSystems = function: nixpkgs.lib.genAttrs systems (system: function {
pkgs = import nixpkgs { inherit system; config.allowUnfree = true; };
});
in {
devShells = forAllSystems ({ pkgs }: {
default = (pkgs.buildFHSUserEnv {
name = "pip-zone";
targetPkgs = pkgs: with pkgs; [
python311Full
python311Packages.pip

postgresql
dbeaver
];
runScript = "zsh || bash";
}).env;
});
};
}
48 changes: 48 additions & 0 deletions backend/project/endpoints/courses/join_codes/course_join_code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""
This file will contain the api endpoints for the /courses/<course_id>/join_codes url
"""

from os import getenv
from urllib.parse import urljoin
from dotenv import load_dotenv

from flask_restful import Resource
from project.utils.query_agent import query_by_id_from_model, delete_by_id_from_model
from project.models.course_share_code import CourseShareCode
from project.utils.authentication import authorize_teacher_of_course

load_dotenv()
API_URL = getenv("API_HOST")
RESPONSE_URL = urljoin(f"{API_URL}/", "courses")

class CourseJoinCode(Resource):
"""
This class will handle post and delete queries to
the /courses/course_id/join_codes/<join_code> url, only an admin of a course can do this
"""

@authorize_teacher_of_course
def get(self, course_id, join_code):
"""
This function will return all the join codes of a course
"""

return query_by_id_from_model(
CourseShareCode,
"join_code",
join_code,
urljoin(f"{RESPONSE_URL}/", f"{str(course_id)}/", "join_codes")
)

@authorize_teacher_of_course
def delete(self, course_id, join_code):
"""
Api endpoint for deleting join codes from a course, can only be done by the teacher
"""

return delete_by_id_from_model(
CourseShareCode,
"join_code",
join_code,
urljoin(f"{RESPONSE_URL}/", f"{str(course_id)}/", "join_codes")
)
58 changes: 58 additions & 0 deletions backend/project/endpoints/courses/join_codes/course_join_codes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""
This file will contain the api endpoints for the /courses/<course_id>/join_codes url
"""

from os import getenv
from urllib.parse import urljoin
from dotenv import load_dotenv

from flask_restful import Resource
from flask import request
from project.utils.query_agent import query_selected_from_model, insert_into_model
from project.models.course_share_code import CourseShareCode
from project.endpoints.courses.courses_utils import get_course_abort_if_not_found
from project.utils.authentication import authorize_teacher_of_course

load_dotenv()
API_URL = getenv("API_HOST")
RESPONSE_URL = urljoin(f"{API_URL}/", "courses")

class CourseJoinCodes(Resource):
"""
This class will handle get and post queries to
the /courses/course_id/join_codes url, only an admin of a course can do this
"""

@authorize_teacher_of_course
def get(self, course_id):
"""
This function will return all the join codes of a course
"""

get_course_abort_if_not_found(course_id)

return query_selected_from_model(
CourseShareCode,
urljoin(f"{RESPONSE_URL}/", f"{str(course_id)}/", "join_codes"),
select_values=["join_code", "expiry_time"],
filters={"course_id": course_id}
)

@authorize_teacher_of_course
def post(self, course_id):
"""
Api endpoint for adding new join codes to a course, can only be done by the teacher
"""

get_course_abort_if_not_found(course_id)

data = request.get_json()
data["course_id"] = course_id

return insert_into_model(
CourseShareCode,
data,
urljoin(f"{RESPONSE_URL}/", f"{str(course_id)}/", "join_codes"),
"join_code",
required_fields=["for_admins"]
)
24 changes: 24 additions & 0 deletions backend/project/endpoints/courses/join_codes/join_codes_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""
This file is used to configure the join codes endpoints.
It is used to define the routes for the join codes blueprint and the
corresponding api endpoints.
The join codes blueprint is used to define the routes for the join codes api
endpoints and the join codes api is used to define the routes for the join codes
api endpoints.
"""

from flask import Blueprint
from flask_restful import Api

from project.endpoints.courses.join_codes.course_join_codes import CourseJoinCodes
from project.endpoints.courses.join_codes.course_join_code import CourseJoinCode

join_codes_bp = Blueprint("join_codes", __name__)
join_codes_api = Api(join_codes_bp)

join_codes_bp.add_url_rule("/courses/<int:course_id>/join_codes",
view_func=CourseJoinCodes.as_view('course_join_codes'))

join_codes_bp.add_url_rule("/courses/<int:course_id>/join_codes/<string:join_code>",
view_func=CourseJoinCode.as_view('course_join_code'))
17 changes: 17 additions & 0 deletions backend/project/endpoints/docs/docs_endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""
Module for defining the swagger docs
"""

from os import getenv
from flask_swagger_ui import get_swaggerui_blueprint

SWAGGER_URL = getenv("DOCS_URL")
API_URL = getenv("DOCS_JSON_PATH")

swagger_ui_blueprint = get_swaggerui_blueprint(
SWAGGER_URL,
f"/{API_URL}",
config={
'app_name': 'Pigeonhole API'
}
)
51 changes: 51 additions & 0 deletions backend/project/endpoints/projects/project_assignment_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""
Module for getting the assignment files
of a project
"""
import os
from urllib.parse import urljoin

from flask import send_from_directory
from werkzeug.utils import safe_join

from flask_restful import Resource

from project.models.project import Project
from project.utils.query_agent import query_by_id_from_model
from project.utils.authentication import authorize_project_visible

API_URL = os.getenv('API_HOST')
RESPONSE_URL = urljoin(API_URL, "projects")
UPLOAD_FOLDER = os.getenv('UPLOAD_URL')

class ProjectAssignmentFiles(Resource):
"""
Class for getting the assignment files of a project
"""

@authorize_project_visible
def get(self, project_id):
"""
Get the assignment files of a project
"""
json, status_code = query_by_id_from_model(
Project,
"project_id",
project_id,
"RESPONSE_URL"
)

if status_code != 200:
return json, status_code

project = json["data"]
file_url = safe_join(UPLOAD_FOLDER, str(project_id))

if not os.path.isfile(safe_join(file_url, project.assignment_file)):
# no file is found so return 404
return {
"message": "No assignment file found for this project",
"url": file_url
}, 404

return send_from_directory(file_url, project.assignment_file)
Loading

0 comments on commit 1fc130b

Please sign in to comment.