Skip to content
Open
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
69 changes: 68 additions & 1 deletion app/django/timetables/management/commands/exportadmins.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
import csv
import sys
import argparse
import itertools

from django.contrib.auth.models import User

from timetables.utils import manage_commands
from timetables import models


ADMIN_PERM_CODENAME = "is_admin"
Expand All @@ -41,10 +43,39 @@ def __init__(self):
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)

subparsers = self.parser.add_subparsers(help="Export type")
read_access = subparsers.add_parser(
"read-access",
help="Export CSV list of CRSIDs with access to view admin area")
read_access.set_defaults(func=self.handle_read_access)
write_access = subparsers.add_parser(
"write-access",
help="Export CSV list of CRSIDs with subjects they can edit")
write_access.set_defaults(func=self.handle_write_access)

def handle(self, args):
# Dispatch to correct handler for subcommand
args.func()

def handle_write_access(self):
admin_users = self.get_admins()

editable_subjects = self.get_editable_subjects_by_crsid(self.get_subjects())

admin_write_access = (
(user.username, subject.get_most_significant_thing().fullpath,
unicode(subject))
for user in admin_users
if user.username in editable_subjects
for subject in editable_subjects[user.username])

csv.writer(sys.stdout).writerows(admin_write_access)

def handle_read_access(self):
admin_users = self.get_admins()

admin_usernames = ((user.username,) for user in admin_users)
admin_usernames = ((user.username,)
for user in admin_users)

csv.writer(sys.stdout).writerows(admin_usernames)

Expand All @@ -53,3 +84,39 @@ def get_admins(self):
user_permissions__codename=ADMIN_PERM_CODENAME,
user_permissions__content_type__app_label=ADMIN_PERM_APP_LABEL)
.order_by("username"))

def get_subjects(self):
return models.Subjects.all_subjects()

@classmethod
def subjects_by_thing_id(cls, subjects):
return dict(
(models.Thing.hash(sub.get_most_significant_thing().fullpath), sub)
for sub in subjects)

def get_editable_subjects_by_crsid(self, subjects):
"""
Get a dict mapping CRSIDs to a set of subjects they can edit.
"""

subjects_by_thing = self.subjects_by_thing_id(subjects)

edit_perms = models.ThingTag.objects.filter(
annotation="admin",
targetthing__pathid__in=subjects_by_thing.keys()
).values_list('thing__name', 'targetthing__pathid')

# Map pathids back to subjects
user_editable_subjects = (
(crsid, subjects_by_thing[pathid])
for (crsid, pathid) in edit_perms
if pathid in subjects_by_thing
)

# Group subjects
by_user = itertools.groupby(sorted(user_editable_subjects),
lambda (crsid, _): crsid)

return dict(
(crsid, set(sub for (_, sub) in group))
for (crsid, group) in by_user)