def UpdateUserPoints(UserID): # Start user point count UserPoints = 0 # Query all complete unique solutions challenges = Challenges.QueryAllChallenges() for challenge in challenges: if Solutions.HasUserSolvedChallenge(UserID, challenge.ChallengeID): UserPoints += Challenges.ChallengeQueryID(challenge.ChallengeID).Points # Query all achievements achievements = Achievements.AchievementsQueryUserID(UserID) for achievement in achievements: UserPoints += int(achievement.AchievementScore) # Update this user's score in the database ExistingUsers = Session.query(UsersTable).filter(UsersTable.UserID == UserID).all() # Commit changes if len(ExistingUsers) == 1: ExistingUsers[0].UserPoints = UserPoints Session.commit() # Post to session if we have a matching ID (otherwise, just return the user points) if session.get("UserID") and session["UserID"] == UserID: session["UserPoints"] = UserPoints session.save() return UserPoints
def results_view(self): # Pull up this user's information UserName = request.path[request.path.find("results/") + 8 : len(request.path)] # Pull up this user's information ExistingUser = Users.UserQueryName(UserName) # Check for existance if not ExistingUser: abort(status_code = 404, detail = "User name \"" + UserName + "\" does not exist.") # Solution list c.solutions = [] # Build a solutions list with connected data (i.e. challenge name, group name, etc..) solutions = Solutions.SolutionsUserID(ExistingUser.UserID) for solution in solutions: # Query the challenge to pull out the title and group name Challenge = Challenges.ChallengeQueryID(solution.ChallengeID) # Query the group ChallengeGroup = Challenges.ChallengesGroupQueryGroupID(Challenge.ChallengeGroupID, False) # Post the challenge title and group name UserSolution = {"SolutionID": solution.SolutionID, "ChallengeID": solution.ChallengeID, "GroupName": ChallengeGroup.ChallengeGroupName, "GroupID": ChallengeGroup.ChallengeGroupID, "ChallengeTitle": Challenge.Title, "SubmissionDate": solution.SubmitDateTime, "MemoryUsage": solution.MemoryUsage, "RuntimeUsage": solution.RuntimeUsage, "ResultCode": solution.ResultCode} # Append to list c.solutions.append(UserSolution) # Render page c.body_content = render("/content_resultsview.html") return render("/theme.html")
def result_view(self): # Is this a logged-in user? If not, forward them to log-in UserID = session.get("UserID") if not UserID: redirect(url(controller="users", action="login")) # Pull up this results's information ResultID = request.path[request.path.find("result/") + 7 : len(request.path)] # Query the results information Solution = Solver.QueryResultID(UserID, ResultID) # If no solution, post error if not Solution: abort(status_code = 404, detail = "Result ID \"" + ResultID + "\" does not exist.") # Query the challenge # Note to self: can I directly access via foriegn key? Challenge = Challenges.ChallengeQueryID(Solution.ChallengeID) if not Challenge: abort(status_code = 404, detail = "Challenge ID \"" + Solution.ChallengeID + "\" does not exist.") # Find all user solutions to this Challenge... Challenge.solutions = Solutions.SolutionsUserIDChallengeID(UserID, Solution.ChallengeID) Challenge.attempts = len(Challenge.solutions) Challenge.solved = False # Check if we have solved this challenge for solution in Challenge.solutions: if solution.ResultCode == 1: Challenge.solved = True break # Post the owner group of this challenge c.groupname = Challenges.ChallengesGroupQueryGroupID(Challenge.ChallengeGroupID, False).ChallengeGroupName # Post the challenge view content c.challenge = Challenge # Post the parent group directory c.group_id = Challenge.ChallengeGroupID c.group_name = c.groupname # Post the user-level directory data c.challenge_id = Challenge.ChallengeID c.challenge_name = Challenge.Title # Convert the source code into html friendly code # NOTE: We are defaulting everything to just render in Python c.formated_code = h.code_to_html(Solution.SourceCode, "Python") c.formated_samplecode = h.code_to_html(Challenge.SampleCode, "Python") # Render the solution information c.challenge = Challenge c.result = Solution c.body_content = render("/content_resultview.html") return render("/theme.html")
def GetUsersByChallenges(): # Get user list ExistingUsers = Session.query(UsersTable).all() # Create challenge count UserChallengesComplete = [] # For each user, find out how many challenges they have complete... for User in ExistingUsers: # Total number of challenges complete ChallengesComplete = 0 # For each challenge, save solved count for Challenge in Challenges.QueryAllChallenges(): if Solutions.HasUserSolvedChallenge(User.UserID, Challenge.ChallengeID): ChallengesComplete += 1 # Push back into the user challenges completion list UserChallengesComplete.append([User, ChallengesComplete]) # Sort the user challenges list UserChallengesComplete.sort(key=lambda x: x[1]) UserChallengesComplete.reverse() # Return the top 10 users return UserChallengesComplete[0:10]
def challenges_view(self): # Query all of the challenges this user is bound to c.challengesview_challengegroup = Challenges.ChallengesQuery() # Render regular form c.body_content = render("/content_challengesview.html") return render("/theme.html")
def challenge_view(self): # Pull up this challenge's information ChallengeID = request.path[request.path.find("challenge/") + 10:len(request.path)] # Is this a valid integer? if not ChallengeID.isdigit(): abort(status_code=404, detail="Challenge ID \"" + ChallengeID + "\" does not exist.") # Query the challenge Challenge = Challenges.ChallengeQueryID(ChallengeID) if Challenge is None: abort(status_code=404, detail="Challenge ID \"" + ChallengeID + "\" failed to load.") if not Challenge.IsValid: abort(status_code=500, detail="Challenge ID \"" + ChallengeID + "\" failed to load: " + Challenge.ErrorStr) # Find all user solutions to this Challenge... Challenge.solutions = Solutions.SolutionsUserIDChallengeID( session.get("UserID"), ChallengeID) Challenge.attempts = len(Challenge.solutions) Challenge.solved = False # Check if we have solved this challenge for solution in Challenge.solutions: if solution.ResultCode == 1: Challenge.solved = True break # Generate graphics / tables self.__generate_graphics(ChallengeID) # Post the owner group of this challenge c.groupname = Challenges.ChallengesGroupQueryGroupID( Challenge.ChallengeGroupID, False).ChallengeGroupName # Convert the source code into html friendly code # NOTE: We are defaulting everything to just render in Python c.formated_code = h.code_to_html(Challenge.StarterCode, "Python") c.formated_samplecode = h.code_to_html(Challenge.SampleCode, "Python") # Post the challenge view content c.challenge = Challenge # Post the parent group directory c.group_id = Challenge.ChallengeGroupID c.group_name = c.groupname # Post the user-level directory data c.challenge_id = Challenge.ChallengeID c.challenge_name = Challenge.Title # Render regular form c.body_content = render("/content_challengeview.html") return render("/theme.html")
def submit_view(self): # Is this a logged-in user? If not, forward them to log-in if not session.get("UserName"): redirect(url(controller="users", action="login")) # Get user ID UserID = session.get("UserID") # Pull up this challenge's information ChallengeID = request.path[request.path.find("submit/") + 7 : len(request.path)] # Is this a valid integer? if not ChallengeID.isdigit(): abort(status_code = 404, detail = "Challenge ID \"" + ChallengeID + "\" does not exist.") # Default form error string c.submit_error = "" # Pull the given post-backs out SourceCode = request.params.get("code") SourceLanguage = request.params.get("language") # Query the challenge Challenge = Challenges.ChallengeQueryID(ChallengeID) if not Challenge: abort(status_code = 404, detail = "Challenge ID \"" + ChallengeID + "\" does not exist.") # Verify file is valid if not Challenge.IsValid: return Challenge.ErrorStr#abort(status_code = 404, detail = "Challenge ID \"" + ChallengeID + "\" failed to load.") # Query associated challenge solutions UserSolutions = Solutions.SolutionsUserIDChallengeID(session.get("UserID"), ChallengeID) Challenge.attempts = len(UserSolutions) Challenge.solved = False # Does the user's solutions contain at least one valid solution? for Attempt in UserSolutions: if Attempt.ResultCode == 1: Challenge.solved = True break # Post the owner group of this challenge c.groupname = Challenges.ChallengesGroupQueryGroupID(Challenge.ChallengeGroupID, False).ChallengeGroupName # Post the challenge view content c.challenge = Challenge # Post the parent group directory c.group_id = Challenge.ChallengeGroupID c.group_name = c.groupname # Post the user-level directory data c.challenge_id = Challenge.ChallengeID c.challenge_name = Challenge.Title # Is this a fresh post-back? if not SourceCode or not SourceLanguage: # Render submission form... c.body_content = render("/form_submit.html") return render("/theme.html") # Else, we need to parse the given code! else: # Solve challenge... # Note to self: in the future, we will have to have an internal queue system that takes # in any number of calls to this function, but only posts back the results when they are ready... ResultID = Solver.SolveChallenge(UserID, ChallengeID, SourceCode, SourceLanguage) redirect(url(controller="result", action=str(ResultID)))
def user_view(self): # Pull up this user's information UserName = request.path[request.path.find("users/") + 6:len(request.path)] # Pull up this user's information ExistingUser = Users.UserQueryName(UserName) # Check for existance if not ExistingUser: abort(status_code=404, detail="User \"" + UserName + "\" does not exist.") # Basic user information c.user = ExistingUser c.user_points = Users.UpdateUserPoints(ExistingUser.UserID) # Post the achivements list c.achievements = Achievements.AchievementsQueryUserID( ExistingUser.UserID) # Find all unique solutions for each challenge, attempts, and succesfull attempts c.complete_challenges = [] c.attempt_count = 0 c.success_count = 0 # Query all challenges and check each one if we have complete it... challenges = Challenges.QueryAllChallenges() for challenge in challenges: # Find all of the solutions for this challenge solutions = ChallengeSolutions = Solutions.SolutionsUserIDChallengeID( ExistingUser.UserID, challenge.ChallengeID) # Add to the number of attempts c.attempt_count += len(solutions) # Add the number of valid attempts for solution in solutions: if solution.ResultCode == 1: c.success_count += 1 # Save any and all solutions for solution in solutions: # Is this a valid solution though? if solution.ResultCode == 1: # Query the challenge to pull out the title and group name Challenge = Challenges.ChallengeQueryID( challenge.ChallengeID) # Query the group ChallengeGroup = Challenges.ChallengesGroupQueryGroupID( Challenge.ChallengeGroupID, False) # Post the challenge title and group name UserSolution = { "ChallengeID": Challenge.ChallengeID, "GroupID": Challenge.ChallengeGroupID, "GroupName": ChallengeGroup.ChallengeGroupName, "ChallengeTitle": Challenge.Title, "ChallengePoints": Challenge.Points } # Put into the list and stop looking for solutions in this group c.complete_challenges.append(UserSolution) break # Post some statistical data / challenge data if c.attempt_count != 0: c.challenge_ratio = "%.2f%% (%d/%d)" % ( float(float(c.success_count) / float(c.attempt_count)) * 100.0, c.success_count, c.attempt_count) else: c.challenge_ratio = "No challenges have been attempted" # Out of all the (valid) solutions, find the fastest (lowest) submission speed and lowest memory usage if len(c.complete_challenges) <= 0: c.fastest_speed = "No accepted solutions" c.smallest_memory = "No accepted solutions" else: c.fastest_speed = sys.maxint c.smallest_memory = sys.maxint # Find all the valid solutions and get the best run-time speeds and memory usage all_solutions = Solutions.SolutionsAcceptedUserID(ExistingUser.UserID) for solution in all_solutions: if solution.RuntimeUsage < c.fastest_speed: c.fastest_speed = solution.RuntimeUsage if solution.MemoryUsage < c.smallest_memory: c.smallest_memory = solution.MemoryUsage # Format string if len(c.complete_challenges) > 0: c.fastest_speed = str(c.fastest_speed) + " milliseconds" c.smallest_memory = str(c.smallest_memory) + " kB" # Render regular form c.body_content = render("/content_userview.html") return render("/theme.html")
def challengegroup_view(self): # Pull up this challenge's information ChallengeGroupID = request.path[request.path.find("challenges/") + 11 : len(request.path)] # Find the challenge description ChallengesID = Challenges.ChallengesQueryGroupID(ChallengeGroupID) # If list is empty, just error out if len(ChallengesID) <= 0: abort(status_code = 404, detail = "No challenges in this challenge group.") # Start challenges meta-info list # Note that the second array is index the same and contains # a tuple representing the (Attempts / All Users) (Solved / All Attempts) ChallengesInfo = [] ChallengePercentage = [] # Query all the challenges associated with this challenge list for ChallengeID in ChallengesID: # PART 1: Get challenge meta data # Get the challenge information ChallengeInfo = Challenges.ChallengeQueryID(ChallengeID) # Query associated challenge solutions UserSolutions = Solutions.SolutionsUserIDChallengeID(session.get("UserID"), ChallengeID) ChallengeInfo.attempts = len(UserSolutions) ChallengeInfo.solved = False # Does the user's solutions contain at least one valid solution? for Attempt in UserSolutions: if Attempt.ResultCode == 1: ChallengeInfo.solved = True break # Put into challenge list ChallengesInfo.append(ChallengeInfo) # PART 2: Get the attempts / all users and solved / attempts percentage UserAttempts = Solutions.GetUserAttemptsCount(ChallengeID) # Number of attempts by users UserCount = Users.UserGetUserCount() TotalSuccess = Solutions.GetSolvedCount(ChallengeID, True) # Yes, count duplicate correct solutions AttemptCount = Solutions.GetAttemptsCount(ChallengeID) # Put into the percentage pair if UserCount != 0: AttemptsPercent = "%.2f" % (100.0 * float(UserAttempts) / float(UserCount)) else: AttemptsPercent = "0.00" if AttemptCount != 0: SolvedPercent = "%.2f" % (100.0 * float(TotalSuccess) / float(AttemptCount)) else: SolvedPercent = "0.00" # Put into percentage list ChallengePercentage.append([AttemptsPercent, SolvedPercent]) # Post the challenges group info into the mako template context c.challengesview_challengesgroup = Challenges.ChallengesGroupQueryGroupID(ChallengeGroupID) # Post the challenges info into the mako template context c.challengesview_challengesmeta = ChallengesInfo c.chalenge_percentage = ChallengePercentage # Post top directory info c.group_name = c.challengesview_challengesgroup.ChallengeGroupName c.group_id = ChallengeGroupID # Render regular form c.body_content = render("/content_challengeslistview.html") return render("/theme.html")
def SolveChallenge(UserID, ChallengeID, ChallengeSourceCode, ChallengeLanguage): # Create a new solutions Solution = UserSolutionsTable() Solution.UserID = UserID Solution.ChallengeID = ChallengeID Solution.ResultCode = 0 Solution.ResultString = "Internal CoreJudge Failure." Solution.SampleResultString = "" # Leave empty Solution.MemoryUsage = 0 Solution.RuntimeUsage = 0 Solution.SourceCode = ChallengeSourceCode Solution.SourceLanguage = ChallengeLanguage Solution.SubmitDateTime = datetime.datetime.now() # Failure flag Failed = False # Load the challenge information Challenge = Challenges.ChallengeQueryID(ChallengeID) if not Challenge: Failed = True # Is this a supported language? # Formally accepted strings: Python, GCC C, C++, Java if not Failed: if ChallengeLanguage != "Python" and ChallengeLanguage != "GCC C" and ChallengeLanguage != "C++" and ChallengeLanguage != "Java": Failed = True # Check source code for viability to execute... if not Failed: SourceSafeErr = __IsSourceSafe(ChallengeSourceCode, ChallengeLanguage) if len(SourceSafeErr) > 0: Failed = True Solution.ResultCode = 8 # Attempt to execute the code against both the challenge test cases and the sample inputs if not Failed: # Execute the sample code Attempt = __ExecuteSource(Challenge.SampleCode, Challenge.SampleInput, Challenge.SampleOutput, ChallengeSourceCode, ChallengeLanguage, True) Solution.ResultString = Attempt.ResultString Solution.SampleResultString = Attempt.ResultString # Execute the official test case # Note that we don't post the result string, we just ignore the output # since we do the comparison of correct I/O within the exec source function Attempt = __ExecuteSource(Challenge.TestCode, Challenge.TestInput, Challenge.TestOutput, ChallengeSourceCode, ChallengeLanguage) Solution.MemoryUsage = Attempt.MemoryUsage Solution.RuntimeUsage = Attempt.RuntimeUsage Solution.ResultCode = Attempt.ResultCode Solution.ResultString = Attempt.ResultString # Commit to DB Session.add(Solution) Session.commit() # Force update the user's score if this solution is valid if Solution.ResultCode == 1: Users.UpdateUserPoints(UserID) # Return this new result ID (So the browser redirects) return Solution.SolutionID