Skip to content
Merged
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
15 changes: 11 additions & 4 deletions Containerfile.debugpy
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
FROM debian:bookworm-slim
FROM python:3.12-slim-trixie
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /usr/src/app
COPY ../../. .
WORKDIR /app
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --locked --no-install-project
COPY . /app
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --extra prod --dev

ENV DEBUG=True
ENV PYTHONUNBUFFERED=1
Expand All @@ -17,7 +25,6 @@ ENV XDMOD_API_URL="localhost"
EXPOSE 8000
EXPOSE 5678

RUN uv sync --extra prod --dev
RUN echo "yes" | uv run manage.py initial_setup
RUN uv run manage.py load_test_data

Expand Down
2 changes: 1 addition & 1 deletion coldfront/config/logging.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.contrib.messages import constants as messages
from coldfront.core.utils.common import import_from_settings
import socket

Check failure on line 3 in coldfront/config/logging.py

View workflow job for this annotation

GitHub Actions / ruff lint

Ruff (I001)

coldfront/config/logging.py:1:1: I001 Import block is un-sorted or un-formatted

# ------------------------------------------------------------------------------
# ColdFront logging config
Expand All @@ -24,7 +24,7 @@
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"root": {"level": "INFO", "handlers": ["file"]},
"root": {"level": "INFO", "handlers": ["console", "file"]},
"formatters": {
"standard": {
"format": "{levelname} {asctime} {module} {thread:d} {message}",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import argparse
import logging

from django.core.management.base import BaseCommand

from coldfront.core.project.models import Project, ProjectUser, ProjectUserRoleChoice, ProjectUserStatusChoice
from coldfront.core.school.models import School
from coldfront.core.user.models import User, ApproverProfile
from coldfront.core.utils.common import import_from_settings

logger = logging.getLogger(__name__)

GENERAL_RESOURCE_NAME = import_from_settings("GENERAL_RESOURCE_NAME")
CENTER_BASE_URL = import_from_settings("CENTER_BASE_URL")


class Command(BaseCommand):
help = "Add a school approver to all projects associated with \
that school as a manager"

def add_arguments(self, parser):
parser.add_argument(
"-u",
"--username",
type=str,
help="Username (NetID) \
of school approver",
)
parser.add_argument(
"-s",
"--school",
type=str,
help="School, i.e. projects associated \
with this school will be modified",
)
parser.add_argument(
"--dry-run",
action=argparse.BooleanOptionalAction,
help="dry run, but log what will be done",
)

def handle(self, *args, **options):
try:
logger.info(
f"""received a request to add '{options["username"]}' to all \
projects associated with school '{options["school"]}'. \
Value of dry run arg is '{options["dry_run"]}'."""
)
approver: User = User.objects.get(username=options["username"])
school: School = School.objects.get(description=options["school"])
dry_run: bool = options["dry_run"]
manager_role: ProjectUserRoleChoice = ProjectUserRoleChoice.objects.get(name="Manager")
active_status: ProjectUserStatusChoice = ProjectUserStatusChoice.objects.get(name="Active")

approver_profile = approver.userprofile.approver_profile
schools_for_approver = approver_profile.schools.all()

if school not in schools_for_approver:
logger.warning(f"User {approver} is not school approver for {school}")
return

projects_for_school = Project.objects.filter(school=school)
for project in projects_for_school:
approver_in_project = ProjectUser.objects.filter(project=project, user=approver).exists()
if not approver_in_project:
logger.info(f"approver '{approver}' not in project '{project}' and will be added")
if not dry_run:
approver_as_manager, status = ProjectUser.objects.get_or_create(
user=approver,
project=project,
role=manager_role,
status=active_status,
)
logger.info(f"Status of adding approver '{approver}' to project '{project}' is '{status}'")

except Exception:
logger.warning("Exception occurred with traceback:", exc_info=True)
Loading
Loading