Skip to content

Commit

Permalink
Updating comments and docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
Dillon Lareau committed Feb 17, 2020
1 parent e6159e6 commit 8712851
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 15 deletions.
4 changes: 2 additions & 2 deletions huntserver/auth_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@


def login_selection(request):
""" A mostly static view to render the login selection. Next url parameter is conserved. """
""" A mostly static view to render the login selection. Next url parameter is preserved. """

if 'next' in request.GET:
context = {'next': request.GET['next']}
Expand Down Expand Up @@ -132,7 +132,7 @@ def shib_login(request):
login(request, user)
logger.info("Shibboleth user logged in: %s" % (str(user)))

# Redirect if nessecary
# Redirect if necessary
if not redirect_url or '//' in redirect_url or ' ' in redirect_url:
redirect_url = settings.LOGIN_REDIRECT_URL
return redirect(redirect_url)
2 changes: 1 addition & 1 deletion huntserver/hunt_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def current_hunt(request):

def prepuzzle(request, prepuzzle_num):
"""
A view to handle answer submissions via POST and render the basic prepuzzle page rendering.
A view to handle answer submissions via POST and render the prepuzzle's template.
"""

puzzle = Prepuzzle.objects.get(pk=prepuzzle_num)
Expand Down
40 changes: 29 additions & 11 deletions huntserver/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,8 @@ class Hunt(models.Model):
default=timezone.now,
help_text="The last time that the periodic update management command was ran")

# A bit of custom logic in clean and save to ensure exactly one hunt's
# is_current_hunt is true at any time. It makes sure you can never un-set the
# value, and setting it anywhere else unsets all others.
def clean(self, *args, **kwargs):
""" Overrides the standard clean method to ensure that only one hunt is the current hunt """
if(not self.is_current_hunt):
try:
old_instance = Hunt.objects.get(pk=self.pk)
Expand All @@ -78,6 +76,7 @@ def clean(self, *args, **kwargs):

@transaction.atomic
def save(self, *args, **kwargs):
""" Overrides the standard save method to ensure that only one hunt is the current hunt """
self.full_clean()
if self.is_current_hunt:
Hunt.objects.filter(is_current_hunt=True).update(is_current_hunt=False)
Expand Down Expand Up @@ -105,7 +104,7 @@ def is_day_of_hunt(self):

@property
def in_reg_lockdown(self):
""" A boolean indicating whether or not today is the day of the hunt """
""" A boolean indicating whether or not registration has locked for this hunt """
return (self.start_date - timezone.now()).days <= settings.HUNT_REGISTRATION_LOCKOUT

@property
Expand All @@ -120,10 +119,12 @@ def season(self):

@property
def real_teams(self):
""" A queryset of all non-dummy teams in the hunt """
return self.team_set.exclude(location="DUMMY").all()

@property
def dummy_team(self):
""" The dummy team for the hunt """
try:
team = self.team_set.get(location="DUMMY")
except Team.DoesNotExist:
Expand All @@ -137,8 +138,8 @@ def __str__(self):
else:
return self.hunt_name

# Takes a user and a hunt and returns either the user's team for that hunt or None
def team_from_user(self, user):
""" Takes a user and a hunt and returns either the user's team for that hunt or None """
if(not user.is_authenticated):
return None
teams = get_object_or_404(Person, user=user).teams.filter(hunt=self)
Expand Down Expand Up @@ -324,9 +325,11 @@ class Team(models.Model):
blank=True,
help_text="The date/time at which a hunt will be archived and available to the public")
last_seen_message = models.IntegerField(
default=0)
default=0,
help_text="The PK of the last message the team has seen")
last_received_message = models.IntegerField(
default=0)
default=0,
help_text="The PK of the last message the team has received")
num_available_hints = models.IntegerField(
default=0,
help_text="The number of hints the team has available to use")
Expand Down Expand Up @@ -355,7 +358,7 @@ def playtest_over(self):

@property
def playtest_happening(self):
""" A boolean indicating whether or not the team's playtest slot has passed """
""" A boolean indicating whether or not the team's playtest slot is currently happening """
return self.playtest_started and not self.playtest_over

@property
Expand All @@ -373,13 +376,16 @@ def short_name(self):

@property
def size(self):
""" The number of people on the team """
return self.person_set.count()

@property
def has_waiting_messages(self):
""" A boolean indicating whether or not the team has waiting chat messages """
return max(self.last_received_message - self.last_seen_message, 0)

def hints_open_for_puzzle(self, puzzle):
""" Takes a puzzle and returns whether or not the team may use hints on the puzzle """
if(self.num_available_hints > 0 or self.hint_set.count() > 0):
try:
unlock = Unlock.objects.get(team=self, puzzle=puzzle)
Expand All @@ -391,6 +397,7 @@ def hints_open_for_puzzle(self, puzzle):
return False

def unlock_puzzles(self):
""" Unlocks all puzzles a team is currently supposed to have unlocked """
puzzles = self.hunt.puzzle_set.all().order_by('puzzle_number')
numbers = []

Expand Down Expand Up @@ -426,10 +433,11 @@ def unlock_puzzles(self):
str(puzzle.puzzle_id)))
Unlock.objects.create(team=self, puzzle=puzzle, time=timezone.now())

# The way this works currently sucks, it should only be called once per solve
# Right now that one place is Submission.respond()
# It also only does # of solves based unlocks. Time based unlocks are done in run_updates
def unlock_hints(self):
""" Gives teams the appropriate number of hints based on "Solves" HintUnlockPlans """
# The way this works currently sucks, it should only be called once per solve
# Right now that one place is Submission.respond()
# It also only does # of solves based unlocks. Time based unlocks are done in run_updates
num_solved = self.solved.count()
plans = self.hunt.hintunlockplan_set
num_hints = plans.filter(unlock_type=HintUnlockPlan.SOLVES_UNLOCK,
Expand All @@ -438,6 +446,7 @@ def unlock_hints(self):
self.save()

def reset(self):
""" Resets/deletes all of the team's progress """
self.unlocked.clear()
self.unlock_set.all().delete()
self.solved.clear()
Expand Down Expand Up @@ -524,13 +533,16 @@ def is_correct(self):

@property
def convert_markdown_response(self):
""" The response with all markdown links converted to HTML links """
return re.sub(r'\[(.*?)\]\((.*?)\)', '<a href="\\2">\\1</a>', self.response_text)

def save(self, *args, **kwargs):
""" Overrides the default save function to update the modified date on save """
self.modified_date = timezone.now()
super(Submission, self).save(*args, **kwargs)

def create_solve(self):
""" Creates a solve based on this submission """
Solve.objects.create(puzzle=self.puzzle, team=self.team, submission=self)
logger.info("Team %s correctly solved puzzle %s" % (str(self.team.team_name),
str(self.puzzle.puzzle_id)))
Expand All @@ -539,6 +551,8 @@ def create_solve(self):
# Returning an empty string means that huntstaff should respond via the queue
# Order of response importance: Regex, Defaults, Staff response.
def respond(self):
""" Takes the submission's text and uses various methods to craft and populate a response.
If the response is correct a solve is created and the correct puzzles are unlocked """
# Compare against correct answer
if(self.is_correct):
# Make sure we don't have duplicate or after hunt submission objects
Expand Down Expand Up @@ -571,6 +585,7 @@ def respond(self):
self.save()

def update_response(self, text):
""" Updates the response with the given text """
self.response_text = text
self.modified_date = timezone.now()
self.save()
Expand Down Expand Up @@ -633,6 +648,7 @@ class Meta:
unique_together = ('puzzle', 'team',)

def serialize_for_ajax(self):
""" Serializes the puzzle, team, and status fields for ajax transmission """
message = dict()
message['puzzle'] = self.puzzle.serialize_for_ajax()
message['team_pk'] = self.team.pk
Expand Down Expand Up @@ -776,13 +792,15 @@ class HintUnlockPlan(models.Model):
help_text="Number of times this Unlock Plan has given a hint")

def reset_plan(self):
""" Resets the HintUnlockPlan """
self.num_triggered = 0

def __str__(self):
return "Nope"


class OverwriteStorage(FileSystemStorage):
""" A custom storage class that just overwrites existing files rather than erroring """
def get_available_name(self, name):
# If the filename already exists, remove it as if it was a true file system
if self.exists(name):
Expand Down
2 changes: 1 addition & 1 deletion huntserver/staff_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ def staff_hints_control(request):
@staff_member_required
def emails(request):
"""
A view to send emails out to hunt participants upon recieveing a valid post request as well as
A view to send emails out to hunt participants upon receiving a valid post request as well as
rendering the staff email form page
"""

Expand Down

0 comments on commit 8712851

Please sign in to comment.