Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Lint

on:
pull_request:

jobs:
run-linters:
name: ESLint + Prettier (frontend)
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./frontend

steps:
- name: Check out Git repository
uses: actions/checkout@v5

- name: Set up Bun
uses: oven-sh/setup-bun@v2

- name: Install Node.js dependencies
run: bun install --frozen-lockfile

- name: Run ESLint
run: bun run lint:strict

- name: Run Prettier format check
run: bun run format:check

ruff:
name: Ruff (backend)
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./backend

steps:
- name: Check out Git repository
uses: actions/checkout@v5

- name: Install uv
uses: astral-sh/setup-uv@v4

- name: Set up Python
run: uv python install

- name: Install backend dependencies
run: uv sync --group dev

- name: Run Ruff lint check
run: uv run ruff check

- name: Run Ruff format check
run: uv run ruff format --check
186 changes: 92 additions & 94 deletions backend/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,28 @@
# Application definition

INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"corsheaders",
"rest_framework",
"hoagieplan",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"corsheaders",
"rest_framework",
"hoagieplan",
]

SECURE_SSL_REDIRECT = os.getenv("SECURE_SSL_REDIRECT", "false").lower() == "true"
SESSION_COOKIE_SECURE = os.getenv("SESSION_COOKIE_SECURE", "false").lower() == "true"

MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",
"django.middleware.security.SecurityMiddleware",
"django.middleware.common.CommonMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"corsheaders.middleware.CorsMiddleware",
"django.middleware.security.SecurityMiddleware",
"django.middleware.common.CommonMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]

AUTHENTICATION_BACKENDS = ("django.contrib.auth.backends.ModelBackend",)
Expand All @@ -69,68 +69,68 @@
LOGS = os.getenv("LOGS", "False").lower() == "true"

LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"standard": {
"format": "{asctime} [{levelname}] {name}: {message}",
"style": "{",
},
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"formatter": "standard",
},
},
"root": {
"handlers": ["console"],
"level": "WARNING",
},
"loggers": {
# Your application
"hoagieplan": {
"level": "DEBUG" if LOGS else "INFO",
"handlers": ["console"],
"propagate": False,
},
# Django internals
"django": {
"level": "INFO",
"handlers": ["console"],
"propagate": False,
},
# SQL queries
"django.db.backends": {
"level": "DEBUG" if LOGS else "WARNING",
"handlers": ["console"],
"propagate": False,
},
# HTTP requests
"django.request": {
"level": "INFO",
"handlers": ["console"],
"propagate": False,
},
},
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"standard": {
"format": "{asctime} [{levelname}] {name}: {message}",
"style": "{",
},
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"formatter": "standard",
},
},
"root": {
"handlers": ["console"],
"level": "WARNING",
},
"loggers": {
# Your application
"hoagieplan": {
"level": "DEBUG" if LOGS else "INFO",
"handlers": ["console"],
"propagate": False,
},
# Django internals
"django": {
"level": "INFO",
"handlers": ["console"],
"propagate": False,
},
# SQL queries
"django.db.backends": {
"level": "DEBUG" if LOGS else "WARNING",
"handlers": ["console"],
"propagate": False,
},
# HTTP requests
"django.request": {
"level": "INFO",
"handlers": ["console"],
"propagate": False,
},
},
}

ROOT_URLCONF = "config.urls"

TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]

WSGI_APPLICATION = "config.wsgi.application"
Expand All @@ -143,9 +143,7 @@
# Select the appropriate database URL based on DEBUG setting
os.environ["DATABASE_URL"] = os.getenv("TEST_DATABASE_URL") if DEBUG else os.getenv("DATABASE_URL")
DATABASES = {
"default": dj_database_url.config(
default=os.getenv("DATABASE_URL"), ssl_require=False, conn_health_checks=True
)
"default": dj_database_url.config(default=os.getenv("DATABASE_URL"), ssl_require=False, conn_health_checks=True)
}

AUTH_USER_MODEL = "hoagieplan.CustomUser"
Expand All @@ -156,30 +154,30 @@
AUTH0_ALGORITHMS = ["RS256"]

REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"hoagieplan.api.auth.auth.Auth0JWTAuthentication",
],
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticated",
],
"DEFAULT_AUTHENTICATION_CLASSES": [
"hoagieplan.api.auth.auth.Auth0JWTAuthentication",
],
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticated",
],
}

# Password validation
# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]


Expand Down
76 changes: 38 additions & 38 deletions backend/config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,46 +28,46 @@
from hoagieplan.api.calendar.calendar_configuration_view import CalendarConfigurationView
from hoagieplan.api.calendar.calendar_event_view import CalendarEventView
from hoagieplan.api.dashboard import (
almost_completed,
comments,
details,
program_details_api,
requirements,
search,
upload,
almost_completed,
comments,
details,
program_details_api,
requirements,
search,
upload,
)
from hoagieplan.api.profile import info, tutorial

urlpatterns = [
# Admin
path("admin/", admin.site.urls),
# Profile
path("profile/get_user/", info.get_user, name="get_user"),
path("profile/update/", info.update_profile, name="update_profile"),
path("profile/class-year/", info.update_class_year, name="update_class_year"),
# Tutorial
path("tutorial/get-status/", tutorial.get_status, name="get_tutorial_status"),
path("tutorial/set-status/", tutorial.set_status, name="set_tutorial_status"),
# Dashboard
path("search/", search.search_courses, name="search"),
path("fetch_courses/", info.get_user_courses, name="fetch_courses"),
path("update_courses/", requirements.update_courses, name="update_courses"),
path("update_transcript_courses/", requirements.update_transcript_courses, name="update_transcript_courses"),
path("manually_settle/", requirements.manually_settle, name="manually_settle"),
path("mark_satisfied/", requirements.mark_satisfied, name="mark_satisfied"),
path("update_requirements/", requirements.update_requirements, name="update_requirements"),
path("requirement_info/", requirements.requirement_info, name="requirement_info"),
path("course/details/", details.course_details, name="course_details"),
path("course/comments/", comments.course_comments_view, name="course_comments"),
path("upload/", upload.upload_file, name="upload_file"),
path("almost_completed/", almost_completed.almost_completed, name="almost_completed"),
path("program_details/<str:code>/", program_details_api.program_details, name="program_details"),
# Calendar
path("export-calendar/", ical_generator.export_calendar_view, name="export_calendar"),
path("calendars/<int:term>/", CalendarConfigurationView.as_view(), name="calendars"),
path(
"calendar_events/<str:calendar_name>/<int:term>/",
CalendarEventView.as_view(),
name="calendar_events",
),
# Admin
path("admin/", admin.site.urls),
# Profile
path("profile/get_user/", info.get_user, name="get_user"),
path("profile/update/", info.update_profile, name="update_profile"),
path("profile/class-year/", info.update_class_year, name="update_class_year"),
# Tutorial
path("tutorial/get-status/", tutorial.get_status, name="get_tutorial_status"),
path("tutorial/set-status/", tutorial.set_status, name="set_tutorial_status"),
# Dashboard
path("search/", search.search_courses, name="search"),
path("fetch_courses/", info.get_user_courses, name="fetch_courses"),
path("update_courses/", requirements.update_courses, name="update_courses"),
path("update_transcript_courses/", requirements.update_transcript_courses, name="update_transcript_courses"),
path("manually_settle/", requirements.manually_settle, name="manually_settle"),
path("mark_satisfied/", requirements.mark_satisfied, name="mark_satisfied"),
path("update_requirements/", requirements.update_requirements, name="update_requirements"),
path("requirement_info/", requirements.requirement_info, name="requirement_info"),
path("course/details/", details.course_details, name="course_details"),
path("course/comments/", comments.course_comments_view, name="course_comments"),
path("upload/", upload.upload_file, name="upload_file"),
path("almost_completed/", almost_completed.almost_completed, name="almost_completed"),
path("program_details/<str:code>/", program_details_api.program_details, name="program_details"),
# Calendar
path("export-calendar/", ical_generator.export_calendar_view, name="export_calendar"),
path("calendars/<int:term>/", CalendarConfigurationView.as_view(), name="calendars"),
path(
"calendar_events/<str:calendar_name>/<int:term>/",
CalendarEventView.as_view(),
name="calendar_events",
),
]
Loading
Loading