Skip to content
38 changes: 21 additions & 17 deletions corpus/corpus/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"farewell.apps.FarewellConfig",
"virtual_expo.apps.VirtualExpoConfig",
"blog",
"smp.apps.SmpConfig",
]

MIDDLEWARE = [
Expand Down Expand Up @@ -271,31 +272,34 @@
},
],
"toolbar": "DefaultToolbarConfig",
"removeDialogTabs": ";".join([
"image:advanced",
"image:Link",
"link:upload",
"table:advanced",
"tableProperties:advanced",
]),
"removeDialogTabs": ";".join(
[
"image:advanced",
"image:Link",
"link:upload",
"table:advanced",
"tableProperties:advanced",
]
),
"linkShowTargetTab": False,
"linkShowAdvancedTab": False,
"height": "250px",
"width": "auto",
"forcePasteAsPlainText": True,
"mathJaxClass": "mathjax-latex",
"mathJaxLib": "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_SVG",
"extraPlugins": ",".join([
"mathjax",
"codesnippet",
"image2",
"uploadimage",
"embed",
"uploadimage",
"tableresize",
]),
"extraPlugins": ",".join(
[
"mathjax",
"codesnippet",
"image2",
"uploadimage",
"embed",
"uploadimage",
"tableresize",
]
),
"filebrowserUploadUrl": "/ckeditor/upload/?responseType=json",
"filebrowserBrowseUrl": "/ckeditor/browse/",
}
}

3 changes: 2 additions & 1 deletion corpus/corpus/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
path("blog/", include("blog.urls")),
path("athenaeum/", include("athenaeum.urls")),
path("newsletter/", include("newsletter.urls")),
path("smp/", include("smp.urls")),
]

if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Empty file added corpus/smp/__init__.py
Empty file.
11 changes: 11 additions & 0 deletions corpus/smp/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.contrib import admin
from smp.models import Program
from smp.models import ProgramMember
from smp.models import Submission
from smp.models import Upload

# Register your models here.
admin.site.register(Program)
admin.site.register(ProgramMember)
admin.site.register(Upload)
admin.site.register(Submission)
12 changes: 12 additions & 0 deletions corpus/smp/admin_urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.urls import path
from smp import admin_views as views

urlpatterns = [
path("dashboard/", views.dashboard, name="smp_admin_dashboard"),
path(
"program/<int:program_id>/add_members/",
views.add_members,
name="smp_admin_add_members",
),
path("<int:program_id>/manage/", views.manage, name="smp_admin_manage"),
]
156 changes: 156 additions & 0 deletions corpus/smp/admin_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
from accounts.models import ExecutiveMember
from accounts.models import User
from config.models import SIG
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db import IntegrityError
from django.db.models import Count
from django.shortcuts import get_object_or_404
from django.shortcuts import redirect
from django.shortcuts import render
from smp.forms import AdminProgramMemberForm
from smp.forms import ProgramFilterForm
from smp.forms import ProgramForm
from smp.models import Program
from smp.models import ProgramMember

from corpus.decorators import ensure_group_membership


@login_required
@ensure_group_membership(group_names=["smp_coordinator"])
def dashboard(request):
programs = Program.objects.all().order_by("-pk")

if request.method == "POST":
program_id = int(request.POST.get("program_id"))
action = request.POST.get("action")
program = get_object_or_404(Program, pk=program_id)

if action == "hide_program":
if not program.hide_program:
program.hide_program = True
program.save()
messages.success(request, "Program has been hidden.")
elif action == "show_program":
if program.hide_program:
program.hide_program = False
program.save()
messages.success(request, "Program is now visible.")
elif action == "delete_program":
program.delete()
messages.success(request, "Program has been deleted.")

return redirect("smp_admin_dashboard")

form = ProgramFilterForm(request.GET)
if form.is_valid():
try:
sig = int(form.cleaned_data.get("sig"))
if sig == -1:
programs = programs.annotate(
sig_count=Count(
"programmember__member__executivemember__sig", distinct=True
)
).filter(sig_count__gte=2)
elif sig != 0:
sig_obj = SIG.objects.filter(pk=sig).first()
if sig_obj:
programs = programs.annotate(
sig_count=Count(
"programmember__member__executivemember__sig", distinct=True
)
).filter(
sig_count=1, programmember__member__executivemember__sig=sig_obj
)
except (ValueError, TypeError):
pass

programs = programs.distinct()
args = {"programs": programs, "form": form}

return render(request, "smp/admin/dashboard.html", args)


@login_required
@ensure_group_membership(group_names=["smp_coordinator"])
def add_members(request, program_id):
program = Program.objects.get(pk=program_id)
mentors = program.mentors()
mentees = program.mentees()

form = AdminProgramMemberForm(initial={"program": program})

if request.method == "POST":
if "add" in request.POST:
form = AdminProgramMemberForm(request.POST)
form.instance.program = program
if form.is_valid():
member = form.cleaned_data["member"]
member_type = form.cleaned_data["member_type"]

if member_type == "Mentor":
if not ExecutiveMember.objects.filter(user=member).exists():
messages.error(
request, "Only Executive Members can be added as mentors."
)
return redirect("smp_admin_add_members", program_id=program.id)

try:
form.save()
except IntegrityError:
messages.error(request, "Member already added to the program.")
return redirect("smp_admin_add_members", program_id=program.id)

messages.success(request, "Member added to program.")
return redirect("smp_admin_add_members", program_id=program.id)
elif "edit" in request.POST:
program_id = int(request.POST.get("program_id"))
member_id = int(request.POST.get("member_id"))
program = Program.objects.get(pk=program_id)
member = User.objects.get(pk=member_id)

try:
program_member = ProgramMember.objects.get(
program=program, member=member
)
program_member.delete()
except ProgramMember.DoesNotExist:
messages.error(request, "Member does not exist for this program.")
return redirect("smp_admin_add_members", program_id=program.id)

messages.success(request, "Members edited in program.")
return redirect("smp_admin_add_members", program_id=program.id)

args = {
"form": form,
"mentors": mentors,
"mentees": mentees,
"program": program,
}

return render(request, "smp/admin/add_members.html", args)


@login_required
@ensure_group_membership(group_names=["smp_coordinator"])
def manage(request, program_id):
program = Program.objects.get(pk=program_id)
form = ProgramForm(instance=program)

if request.method == "POST":
form = ProgramForm(request.POST, request.FILES, instance=program)
if form.is_valid():
form.save()
messages.success(request, "Program updated successfully!")
return redirect("smp_admin_dashboard")

is_smp_coordinator = request.user.groups.filter(name="smp_coordinator").exists()

args = {
"program": program,
"form": form,
"admin": is_smp_coordinator,
}

return render(request, "smp/mentors/edit_program.html", args)
6 changes: 6 additions & 0 deletions corpus/smp/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class SmpConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "smp"
71 changes: 71 additions & 0 deletions corpus/smp/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from accounts.models import User
from config.models import SIG
from django import forms
from smp.models import Program
from smp.models import ProgramMember
from smp.models import Submission
from smp.models import Upload

from corpus.forms import CorpusForm
from corpus.forms import CorpusModelForm


class ProgramFilterForm(CorpusForm):
sig = forms.ChoiceField(choices=[])
year = forms.ChoiceField(choices=[], required=False)

def __init__(self, *args, **kwargs):
super(ProgramFilterForm, self).__init__(*args, **kwargs)

sig_choices = [(0, "All SIGs"), (-1, "Inter-SIG")] + list(
SIG.objects.values_list("id", "name")
)
year_choices = [(0, "All Years")] + [
(x, x)
for x in list(Program.objects.values_list("year", flat=True).distinct())
]

self.fields["sig"].choices = sig_choices
self.fields["year"].choices = year_choices


class ProgramForm(CorpusModelForm):
class Meta:
model = Program
fields = [
"title",
"abstract",
"thumbnail",
"year",
"description",
"hide_program",
]


class ProgramMemberForm(CorpusModelForm):
class Meta:
model = ProgramMember
fields = ["member"]

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
executive_users = User.objects.filter(executivemember__isnull=False).distinct()
self.fields["member"].queryset = executive_users


class UploadForm(CorpusModelForm):
class Meta:
model = Upload
fields = ["title", "upload_type", "content"]


class SubmissionForm(CorpusModelForm):
class Meta:
model = Submission
fields = ["title", "link"]


class AdminProgramMemberForm(CorpusModelForm):
class Meta:
model = ProgramMember
fields = ["member", "member_type"]
22 changes: 22 additions & 0 deletions corpus/smp/mentor_urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from django.urls import path
from smp import mentor_views as views

urlpatterns = [
path("dashboard/", views.dashboard, name="smp_mentors_dashboard"),
Comment thread
CodePokeX marked this conversation as resolved.
path("program/new/", views.new_program, name="smp_mentors_new_program"),
path(
"program/<int:program_id>/edit/",
views.edit_program,
name="smp_mentors_edit_program",
),
path(
"program/<int:program_id>/add_members/",
views.add_members,
name="smp_mentors_add_members",
),
path(
"program/<int:program_id>/upload/",
views.uploads,
name="smp_mentors_add_upload",
),
]
Loading