示例#1
0
    def on_message(self, message):
        if not self.current_user.is_authenticated():
            self.write_message({"error": "logged_out"})
            return False

        obj = loads(message)
        data = ObjectDict()

        if settings.DEBUG:
            print(obj)
            data.debug = True

        if obj.get("echo"):
            data.echo = obj["echo"]

        if obj.get("competition"):
            self.competition = obj["competition"]
            self._competition = Competition.objects.get(pk=self.competition)
            listeners.competitions[self.competition][
                self.current_user.id].append(self)
            load_competition(self.competition)

        if obj.get("mode"):
            if (obj["mode"] != "compete" and self._competition.get_role(
                    self.current_user) == "compete"):
                data.error = "Unauthorized mode"
            else:
                self.mode = obj["mode"]

        if obj.get("problem"):
            if obj["problem"] != self.problem:
                if self.problem:
                    listeners.problems[self.problem][
                        self.current_user.id].remove(self)
                self.problem = obj["problem"]
                self._problem = Problem.objects.get(pk=self.problem)
                listeners.problems[self.problem][self.current_user.id].append(
                    self)
            data.problem_name = self._problem.name
            data.description = self._problem.description
            if self.mode == "compete":
                data.runs = get_runs_for_player(self.problem,
                                                self.current_user.id, False)
            elif self._competition.get_role(self.current_user) != "compete":
                data.expected_output = self._problem.expected_output
                data.players = get_players(self.problem)

        if obj.get("player") and self._competition.get_role(
                self.current_user) != "compete":
            if obj["player"] != self.player:
                self.player = int(obj["player"])
                data.runs = get_runs_for_player(self.problem, self.player,
                                                True)

        if obj.get("main_file"):
            last_run = Run.objects.filter(
                user=self.current_user.id,
                problem=self.problem).order_by("-number")
            if last_run.exists():
                number = last_run.values_list("number", flat=True)[0] + 1
            else:
                number = 1
            run = Run(number=number,
                      problem_id=self.problem,
                      user=self.current_user,
                      language_id=obj["language"],
                      is_a_test=obj["test_run"],
                      time_to_submission=(
                          self._competition.original_time_left -
                          (competitions[self._competition.id].end_time -
                           time.time())),
                      runtime=None)
            run.main_file.save(
                obj["main_file"]["name"],
                ContentFile(obj["main_file"]["contents"].replace("\r", "")))
            for i in obj["extra_files"]:
                extra_file = ExtraFile(run=run)
                extra_file.file.save(
                    i["name"], ContentFile(i["contents"].replace("\r", "")))
            data.upload = {"id": run.id, "number": run.number}
            data.runs = get_runs_for_player(self.problem, self.current_user.id,
                                            False)

            if len(data.runs) == 1:
                for i in listeners.problems[self.problem].values():
                    for j in [j for j in i if j.mode == "judge"]:
                        j.write_message({"players": get_players(self.problem)})
            else:
                for i in [
                        i for l in listeners.problems[self.problem].values()
                        for i in l
                ]:
                    if i.player == self.current_user.id:
                        if run.is_a_test:
                            i.write_message({
                                "runs": data.runs,
                            })
                        else:
                            i.write_message({
                                "runs":
                                data.runs,
                                "notify":
                                "{} uploaded Run #{}".format(
                                    get_full_name(self.current_user),
                                    run.number),
                                "notif_type":
                                "info",
                                "icon":
                                "send",
                            })
            runloop.request_run(run, (self.run_complete, (run, )))

        if obj.get("judgement"):
            run = Run.objects.get(pk=obj["run"])
            run.judgement = obj["judgement"]
            run.score = obj["score"]
            run.notes = obj["notes"]
            run.save()
            update_score(run.user_id, self.competition)

            run_users = [
                i for i in listeners.competitions[self.competition].get(
                    run.user_id, [])
                if (hasattr(i, "mode") and i.mode == "compete")
            ]
            for run_user in run_users:
                if run_user.problem == run.problem_id:
                    problem_text = ""
                else:
                    problem_text = " of problem {}".format(run.problem.name)
                run_user.write_message({
                    "notify":
                    "Run #{}{} was judged '{}' with a score of {} by {}".
                    format(run.number, problem_text, run.judgement, run.score,
                           get_full_name(self.current_user)),
                    "notif_title":
                    "Judgement for Run #{}{}".format(run.number, problem_text),
                    "notif_type":
                    "success" if run.judgement == "Correct" else "danger",
                    "link":
                    "#{}-&&{}".format(run.problem_id, run.id),
                    "icon":
                    "star",
                })
            for listener in listeners.problems[self.problem].get(
                    run.user_id, []):
                listener.write_message({
                    "runs":
                    get_runs_for_player(self.problem, run.user_id,
                                        self.mode == "judge")
                })
            data.notify = "Saved judgement for {}'s Run #{}".format(
                get_full_name(run.user), run.number)
            data.notif_title = "Saved Judgement"
            data.notif_type = "info"
            data.icon = "saved"

        if obj.get("request"):
            run = Run.objects.get(pk=obj["request"])
            players = [
                i for i in listeners.problems[run.problem_id].get(
                    run.user_id, []) if i.mode == "compete"
            ]
            if self.mode != "compete" and len(players) > 0:
                handlers = players
            else:
                handlers = [self]
            runloop.request_run(
                run, ((lambda handlers, run, u:
                       [handler.run_complete(run, u) for handler in handlers]),
                      (handlers, run, get_full_name(self.current_user))),
                4 if self.mode == "compete" else 3)
            data.notify = "Run requested for {}Run #{}.".format(
                (get_full_name(run.user) +
                 "'s " if self.mode != "compete" else ""), run.number)
            data.notif_title = "Run Requested"
            data.notif_type = "info"
            data.icon = "saved"

        if obj.get("clock") and (self._competition.get_role(self.current_user)
                                 != "compete"):
            competition_clock_operation(obj["clock"], self._competition)

        if len(data) > 0:
            try:
                self.write_message(data)
            except WebSocketClosedError:
                pass