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
1 change: 1 addition & 0 deletions src/teams/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Teams application."""
37 changes: 27 additions & 10 deletions src/teams/admin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
"""Django admin for teams."""
from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from typing import ClassVar

from django.db.models import QuerySet
from django.http import HttpRequest

from django.contrib import admin

from camps.utils import CampPropertyListFilter
Expand All @@ -14,26 +23,30 @@

@admin.register(TeamTask)
class TeamTaskAdmin(admin.ModelAdmin):
list_display = ["id", "team", "name", "description"]
"""Django admin for team tasks."""
list_display: ClassVar[list[str]] = ["id", "team", "name", "description"]


class TeamMemberInline(admin.TabularInline):
"""Django admin inline field for team member."""
model = TeamMember


@admin.register(Team)
class TeamAdmin(admin.ModelAdmin):
"""Django admin for teams."""
save_as = True

@admin.display(
description="Leads",
)
def get_leads(self, obj):
def get_leads(self, obj: Team) -> str:
"""Method to return team leads."""
return ", ".join(
[lead.profile.public_credit_name for lead in obj.leads.all()],
)

list_display = [
list_display: ClassVar[list[str]] = [
"name",
"camp",
"get_leads",
Expand All @@ -46,24 +59,26 @@ def get_leads(self, obj):
"private_irc_channel_managed",
]

list_filter = [
list_filter: ClassVar[list[str]] = [
CampPropertyListFilter,
"needs_members",
"public_irc_channel_bot",
"public_irc_channel_managed",
"private_irc_channel_bot",
"private_irc_channel_managed",
]
inlines = [TeamMemberInline]
inlines: ClassVar[list] = [TeamMemberInline]


@admin.register(TeamMember)
class TeamMemberAdmin(admin.ModelAdmin):
list_filter = [CampPropertyListFilter, "team", "approved"]
"""Django admin for team members."""
list_filter: ClassVar[list] = [CampPropertyListFilter, "team", "approved"]

actions = ["approve_membership", "remove_member"]
actions: ClassVar[list[str]] = ["approve_membership", "remove_member"]

def approve_membership(self, request, queryset) -> None:
def approve_membership(self, request: HttpRequest, queryset: QuerySet) -> None:
"""Method for approving team membership status."""
teams_count = queryset.values("team").distinct().count()
updated = 0

Expand All @@ -80,7 +95,8 @@ def approve_membership(self, request, queryset) -> None:

approve_membership.description = "Approve membership."

def remove_member(self, request, queryset) -> None:
def remove_member(self, request: HttpRequest, queryset: QuerySet) -> None:
"""Method for removing team membership status."""
teams_count = queryset.values("team").distinct().count()
updated = 0

Expand All @@ -99,4 +115,5 @@ def remove_member(self, request, queryset) -> None:

@admin.register(TeamShift)
class TeamShiftAdmin(admin.ModelAdmin):
list_filter = ["team"]
"""Django admin for team shifts."""
list_filter: ClassVar[list[str]] = ["team"]
6 changes: 5 additions & 1 deletion src/teams/apps.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""App config for the teams application."""
from __future__ import annotations

from django.apps import AppConfig
Expand All @@ -10,10 +11,13 @@


class TeamsConfig(AppConfig):
"""App config for the signals connected to the teams application."""
name = "teams"

def ready(self) -> None:
# connect the post_save signal, always including a dispatch_uid to prevent it being called multiple times in corner cases
"""Method to connect the signals."""
# connect the post_save signal, always including a dispatch_uid to prevent
# it being called multiple times in corner cases
post_save.connect(
teammember_saved,
sender="teams.TeamMember",
Expand Down
14 changes: 11 additions & 3 deletions src/teams/email.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
"""Email functions of teams application."""
from __future__ import annotations

import logging
from typing import TYPE_CHECKING

from utils.email import add_outgoing_email

if TYPE_CHECKING:
from django.forms import Form

logger = logging.getLogger(f"bornhack.{__name__}")


def add_added_membership_email(membership):
def add_added_membership_email(membership: Form) -> bool:
"""Method to send email when team membership added."""
formatdict = {"team": membership.team.name, "camp": membership.team.camp.title}

return add_outgoing_email(
Expand All @@ -21,7 +27,8 @@ def add_added_membership_email(membership):
)


def add_removed_membership_email(membership):
def add_removed_membership_email(membership: Form) -> bool:
"""Method to send email when team membership removed."""
formatdict = {"team": membership.team.name, "camp": membership.team.camp.title}

if membership.approved:
Expand All @@ -42,7 +49,8 @@ def add_removed_membership_email(membership):
)


def add_new_membership_email(membership):
def add_new_membership_email(membership: Form) -> bool:
"""Method to send email when team membership requested."""
formatdict = {
"team": membership.team.name,
"camp": membership.team.camp.title,
Expand Down
39 changes: 39 additions & 0 deletions src/teams/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Exceptions for phonebook."""

from __future__ import annotations

import logging

from django.core.exceptions import ValidationError

logger = logging.getLogger(f"bornhack.{__name__}")


class ReservedIrcNameError(ValidationError):
"""Exception raised on reserved irc name."""

def __init__(self) -> None:
"""Exception raised on reserved irc name."""
super().__init__("The public IRC channel name is reserved")


class IrcChannelInUseError(ValidationError):
"""Exception raised a public irc channel is in use."""

def __init__(self) -> None:
"""Exception raised a public irc channel is in use."""
super().__init__("The public IRC channel name is already in use on another team!")

class StartAfterEndError(ValidationError):
"""Exception raised when start date is after end date."""

def __init__(self) -> None:
"""Exception raised when start date is after end date."""
super().__init__("Start can not be after end.")

class StartSameAsEndError(ValidationError):
"""Exception raised when start date is the same as end date."""

def __init__(self) -> None:
"""Exception raised when start date is the same as end date."""
super().__init__("Start can not be the same as end.")
3 changes: 3 additions & 0 deletions src/teams/factories.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Factories for the teams application."""
from __future__ import annotations

import factory
Expand All @@ -6,7 +7,9 @@


class TeamFactory(factory.django.DjangoModelFactory):
"""Team Factory for bootstrapping data."""
class Meta:
"""Meta."""
model = Team

camp = factory.SubFactory("camps.factories.CampFactory")
Expand Down
Loading
Loading