def promote_leader(self, hackathon_id, team_name, new_leader_id): """ team leader promote some one from team to become team leader :type hackathon_id: int :param hackathon_id: hackathon id :type team_name: str|unicode :param team_name: team name :type new_leader_id: int :param new_leader_id: id of user who will become new leader of the team :rtype: bool :return: if promote success, return ok. if not ,return bad request. """ team = self.__get_team_by_name(hackathon_id, team_name) if not team: return not_found("team doesn't exist") self.__validate_team_permission(hackathon_id, team, g.user) # check new leader and old leader in same team member = team.user_team_rels.filter_by(user_id=new_leader_id).first() if not member: return precondition_failed( "Please promote someone in the same team.") if member.status != TeamMemberStatus.Approved: return precondition_failed("The member is not approved yet") team.leader_id = new_leader_id self.db.commit() self.log.debug(team.leader.name + " has been promote to leader.") return team.dic()
def join_team(self, user, team_id): """Join a team will create a record on user_team_rel table which status will be 0. :type user: User :rtype: dict :return: if user already joined team or team not exist, return bad request. Else, return a dict of joined details. """ if Team.objects(id=team_id, members__user=user.id).count(): return ok("You already joined this team.") team = self.__get_team_by_id(team_id) if not team: return not_found() cur_team = self.__get_valid_team_by_user(user.id, team.hackathon.id) if cur_team and cur_team.members.count() > 1: return precondition_failed("Team leader cannot join another team for team member count greater than 1") if not self.register_manager.is_user_registered(user.id, team.hackathon): return precondition_failed("user not registerd") mem = TeamMember( join_time=self.util.get_now(), status=TEAM_MEMBER_STATUS.INIT, user=user) team.members.append(mem) team.save() return to_dic(mem)
def promote_leader(self, hackathon_id, team_name, new_leader_id): """ team leader promote some one from team to become team leader :type hackathon_id: int :param hackathon_id: hackathon id :type team_name: str|unicode :param team_name: team name :type new_leader_id: int :param new_leader_id: id of user who will become new leader of the team :rtype: bool :return: if promote success, return ok. if not ,return bad request. """ team = self.__get_team_by_name(hackathon_id, team_name) if not team: return not_found("team doesn't exist") self.__validate_team_permission(hackathon_id, team, g.user) # check new leader and old leader in same team member = team.user_team_rels.filter_by(user_id=new_leader_id).first() if not member: return precondition_failed("Please promote someone in the same team.") if member.status != TeamMemberStatus.Approved: return precondition_failed("The member is not approved yet") team.leader_id = new_leader_id self.db.commit() self.log.debug(team.leader.name + " has been promote to leader.") return team.dic()
def create_registration(self, hackathon, user, args): """Register hackathon for user Will add a new record in table UserRegistrationRel if precondition fulfilled """ self.log.debug("create_register: %r" % args) user_id = args['user_id'] check_login_provider = self.__is_user_hackathon_login_provider(user, hackathon) if check_login_provider["fail"]: return login_provider_error( "hackathon registration not login provider", friendly_message="当前黑客松活动只是使用" + ",".join(check_login_provider["provides"]) + "账户才能报名", provides=",".join(check_login_provider["provides"])) if self.is_user_registered(user.id, hackathon): self.log.debug("user %s already registered on hackathon %s" % (user_id, hackathon.id)) return self.get_registration_detail(user, hackathon) if self.admin_manager.is_hackathon_admin(hackathon.id, user.id): return precondition_failed("administrator cannot register the hackathon", friendly_message="管理员或裁判不能报名") if hackathon.registration_start_time and hackathon.registration_start_time > self.util.get_now(): return precondition_failed("hackathon registration not opened", friendly_message="报名尚未开始") if hackathon.registration_end_time and hackathon.registration_end_time < self.util.get_now(): return precondition_failed("hackathon registration has ended", friendly_message="报名已经结束") if self.__is_hackathon_filled_up(hackathon): return precondition_failed("hackathon registers reach the upper threshold", friendly_message="报名人数已满") try: is_auto_approve = hackathon.config.get(HACKATHON_CONFIG.AUTO_APPROVE, True) status = HACK_USER_STATUS.AUTO_PASSED if is_auto_approve else HACK_USER_STATUS.UNAUDIT args.pop("user_id") args.pop("hackathon_id") user_hackathon = UserHackathon.objects(user=user, hackathon=hackathon).first() if not user_hackathon: user_hackathon = UserHackathon.objects.create( user=user, hackathon=hackathon, status=status, **args) else: # visitor -> competitor user_hackathon.role = HACK_USER_TYPE.COMPETITOR user_hackathon.status = status user_hackathon.save() # create a team as soon as user registration approved(auto or manually) if is_auto_approve: self.team_manager.create_default_team(hackathon, user) self.__ask_for_dev_plan(hackathon, user) self.__update_register_stat(hackathon) return user_hackathon.dic() except Exception as e: self.log.error(e) return internal_server_error("fail to create register")
def join_team(self, user, team_id): """Join a team will create a record on user_team_rel table which status will be 0. :type user: User :rtype: dict :return: if user already joined team or team not exist, return bad request. Else, return a dict of joined details. """ if Team.objects(id=team_id, members__user=user.id).count(): return ok("You already joined this team.") team = self.__get_team_by_id(team_id) if not team: return not_found() cur_team = self.__get_valid_team_by_user(user.id, team.hackathon.id) if cur_team and cur_team.members.count() > 1: return precondition_failed( "Team leader cannot join another team for team member count greater than 1" ) if not self.register_manager.is_user_registered( user.id, team.hackathon): return precondition_failed("user not registerd") mem = TeamMember(join_time=self.util.get_now(), status=TEAM_MEMBER_STATUS.INIT, user=user) team.members.append(mem) team.save() return to_dic(mem)
def join_team(self, user, team_id): """Join a team will create a record on user_team_rel table which status will be 0. :type user: User :param user: the user to join a team :rtype: dict :return: if user already joined team or team not exist, return bad request. Else, return a dict of joined details. """ if self.db.find_first_object_by(UserTeamRel, user_id=user.id, team_id=team_id): return ok("You already joined this team.") team = self.__get_team_by_id(team_id) if not team: return not_found() cur_team = self.__get_valid_team_by_user(user.id, team.hackathon_id) if cur_team and cur_team.team.user_team_rels.count() > 1: return precondition_failed("Team leader cannot join another team for team member count greater than 1") if not self.register_manager.is_user_registered(user.id, team.hackathon): return precondition_failed("user not registerd") candidate = UserTeamRel(join_time=self.util.get_now(), update_time=self.util.get_now(), status=TeamMemberStatus.Init, hackathon_id=team.hackathon.id, user_id=user.id, team_id=team.id) self.db.add_object(candidate) return candidate.dic()
def create_registration(self, hackathon, user, args): """Register hackathon for user Will add a new record in table UserRegistrationRel if precondition fulfilled """ self.log.debug("create_register: %r" % args) user_id = args['user_id'] check_login_provider = self.__is_user_hackathon_login_provider( user, hackathon) if check_login_provider["fail"]: return login_provider_error( "hackathon registration not login provider", friendly_message="当前黑客松活动只是使用" + ",".join(check_login_provider["provides"]) + "账户才能报名", provides=",".join(check_login_provider["provides"])) if self.is_user_registered(user.id, hackathon): self.log.debug("user %d already registered on hackathon %d" % (user_id, hackathon.id)) return self.get_registration_detail(user, hackathon) if self.admin_manager.is_hackathon_admin(hackathon.id, user.id): return precondition_failed( "administrator cannot register the hackathon", friendly_message="管理员或裁判不能报名") if hackathon.registration_start_time and hackathon.registration_start_time > self.util.get_now( ): return precondition_failed("hackathon registration not opened", friendly_message="报名尚未开始") if hackathon.registration_end_time and hackathon.registration_end_time < self.util.get_now( ): return precondition_failed("hackathon registration has ended", friendly_message="报名已经结束") if self.__is_hackathon_filled_up(hackathon): return precondition_failed( "hackathon registers reach the upper threshold", friendly_message="报名人数已满") try: args["status"] = RGStatus.AUTO_PASSED if hackathon.is_auto_approve( ) else RGStatus.UNAUDIT args['create_time'] = self.util.get_now() user_hackathon_rel = self.db.add_object_kwargs( UserHackathonRel, **args).dic() # create a team as soon as user registration approved(auto or manually) if hackathon.is_auto_approve(): self.team_manager.create_default_team(hackathon, user) self.__update_register_stat(hackathon) return user_hackathon_rel except Exception as e: self.log.error(e) return internal_server_error("fail to create register")
def leave_team(self, hackathon_id, team_name): """Leave a team by user :type hackathon_id: int :param hid: hackathon id :type team_name: str|unicode :param team_name: team name :rtype: bool :return: if leave_team success, return ok. if not ,return bad request. """ team = self.__get_team_by_name(hackathon_id, team_name) if not team: # if team don't exist, do nothing return ok() # if user is not team leader if team.leader_id != g.user.id: self.db.delete_all_objects_by(UserTeamRel, hackathon_id=hackathon_id, user_id=g.user.id) return ok("You have left the team") # if user is team leader if len(self.__get_team_members(team)) >= 2: return precondition_failed("Please promote a new team leader, before leave team.") else: return self.dismiss_team(hackathon_id, team_name)
def join_team(self, hackathon_id, team_name, user): """Join a team will create a record on user_team_rel table which status will be 0. :type hackathon_id: int :param hackathon_id: hackathon id :type team_name: str | unicode :param team_name: team name :type user: User :param user: the user to join a team :rtype: dict :return: if user already joined team or team not exist, return bad request. Else, return a dict of joined details. """ if self.db.find_first_object_by(UserTeamRel, hackathon_id=hackathon_id, user_id=g.user.id): return precondition_failed("You have joined another team, please quit first.") team = self.__get_team_by_name(hackathon_id, team_name) if team: candidate = UserTeamRel(join_time=self.util.get_now(), update_time=self.util.get_now(), status=TeamMemberStatus.Init, hackathon_id=hackathon_id, user_id=user.id, team_id=team.id) self.db.add_object(candidate) return candidate.dic() else: return not_found("team not found !")
def update_team(self, kwargs): """Update existing team information :type kwargs: dict :param kwargs: a dict to store update information for team :rtype: dict :return: updated team information in a dict """ if "id" not in kwargs: return bad_request("Please choose a team to update") team = self.__get_team_by_id(kwargs["id"]) if not team: return not_found("team not exists") # avoid duplicate team with same names if "team_name" in kwargs and kwargs["team_name"] != team.name: if self.__get_team_by_name(g.hackathon.id, kwargs["team_name"]): return precondition_failed("team with the same name exists already") self.__validate_team_permission(g.hackathon.id, team, g.user) self.db.update_object(team, name=kwargs.get("team_name", team.name), description=kwargs.get("description", team.description), git_project=kwargs.get("git_project", team.git_project), logo=kwargs.get("logo", team.logo), update_time=self.util.get_now()) return team.dic()
def leave_team(self, hackathon_id, team_name): """Leave a team by user :type hackathon_id: int :param hid: hackathon id :type team_name: str|unicode :param team_name: team name :rtype: bool :return: if leave_team success, return ok. if not ,return bad request. """ team = self.__get_team_by_name(hackathon_id, team_name) if not team: # if team don't exist, do nothing return ok() # if user is not team leader if team.leader_id != g.user.id: self.db.delete_all_objects_by(UserTeamRel, hackathon_id=hackathon_id, user_id=g.user.id) return ok("You have left the team") # if user is team leader if len(self.__get_team_members(team)) >= 2: return precondition_failed( "Please promote a new team leader, before leave team.") else: return self.dismiss_team(hackathon_id, team_name)
def update_team(self, kwargs): """Update existing team information :type kwargs: dict :param kwargs: a dict to store update information for team :rtype: dict :return: updated team information in a dict """ if "id" not in kwargs: return bad_request("Please choose a team to update") team = self.__get_team_by_id(kwargs["id"]) if not team: return not_found("team not exists") # avoid duplicate team with same names if "team_name" in kwargs and kwargs["team_name"] != team.name: if self.__get_team_by_name(g.hackathon.id, kwargs["team_name"]): return precondition_failed( "team with the same name exists already") self.__validate_team_permission(g.hackathon.id, team, g.user) self.db.update_object(team, name=kwargs.get("team_name", team.name), description=kwargs.get("description", team.description), git_project=kwargs.get("git_project", team.git_project), logo=kwargs.get("logo", team.logo), update_time=self.util.get_now()) return team.dic()
def kick_or_leave(self, operator, team_id, user_id): try: team = Team.objects(id=team_id, members__user=user_id).first() except ValidationError: return not_found() if not team: return not_found() mem = [x for x in team.members if str(x.user.id) == user_id] assert len(mem) < 2 if not mem: return not_found() mem = mem[0] hackathon = team.hackathon user = mem.user if str( team.leader.id ) == user_id: # if the user to be leaved or kicked is team leader return precondition_failed("leader cannot leave team") if str(operator.id) == user_id: # leave team team.members.remove(mem) team.save() self.create_default_team(hackathon, user) else: # kick somebody else self.__validate_team_permission(hackathon.id, team, operator) team.members.remove(mem) team.save() self.create_default_team(hackathon, user) return ok()
def create_default_team(self, hackathon, user): """Create a default new team for user after registration. Use user name as team name by default. Append user id in case user name is duplicate """ user_team_rel = self.__get_valid_team_by_user(user.id, hackathon.id) if user_team_rel: self.log.debug("fail to create team since user is already in some team.") return precondition_failed("you must leave the current team first") team_name = self.__generate_team_name(hackathon, user) team = Team(name=team_name, leader_id=user.id, logo=user.avatar_url, hackathon_id=hackathon.id) self.db.add_object(team) user_team_rel = UserTeamRel(join_time=self.util.get_now(), status=TeamMemberStatus.Approved, hackathon_id=hackathon.id, user_id=user.id, team_id=team.id) self.db.add_object(user_team_rel) return team.dic()
def update_team_member_status(self, operator, user_team_rel_id, status): """ update user's status on selected team. if current user doesn't have permission, return bad request. Else, update user's status :type status: int :param status: the status of the team member, see TeamMemberStatus in constants.py :rtype: bool :return: if update success, return ok. if not , return bad request. """ rel = self.db.find_first_object_by(UserTeamRel, id=user_team_rel_id) if not rel: return not_found() team = rel.team self.__validate_team_permission(rel.hackathon_id, team, operator) if rel.user_id == team.leader_id: return precondition_failed("cannot update status of team leader") if status == TeamMemberStatus.Approved: # disable previous team first self.db.delete_all_objects_by(UserTeamRel, hackathon_id=rel.hackathon_id, user_id=rel.user_id, status=TeamMemberStatus.Approved) self.db.delete_all_objects_by(Team, hackathon_id=rel.hackathon_id, leader_id=rel.user_id) rel.status = TeamMemberStatus.Approved rel.update_time = self.util.get_now() self.db.commit() return ok("approved") if status == TeamMemberStatus.Denied: self.db.delete_object(rel) return ok("Your request has been denied, please rejoin another team.")
def grant_award_to_team(self, hackathon, context): team = self.__get_team_by_id(context.team_id) if not team: return not_found("team not found") award = self.db.find_first_object_by(Award, id=context.award_id) if not award: return not_found("award not found") if team.hackathon_id != hackathon.id or award.hackathon_id != hackathon.id: return precondition_failed("hackathon doesn't match") exist = self.db.find_first_object_by(TeamAward, team_id=context.team_id, award_id=context.award_id) if not exist: exist = TeamAward( team_id=context.team_id, hackathon_id=hackathon.id, award_id=context.award_id, reason=context.get("reason"), level=award.level, ) self.db.add_object(exist) else: exist.reason = context.get("reason", exist.reason) self.db.commit() return self.__award_with_detail(exist)
def start_expr(self, hackathon_name, template_name, user_id): """ A user uses a template to start a experiment under a hackathon :param hackathon_name: :param template_name: :param user_id: :return: """ hack_temp = self.__check_template_status(hackathon_name, template_name) if hack_temp is None: return not_found('hackathon or template is not existed') hackathon = hack_temp[0] # if not self.register_manager.is_user_registered(user_id, hackathon): # return forbidden("user not registered or not approved") if hackathon.event_end_time < self.util.get_now(): self.log.warn( "hackathon is ended. The expr starting process will be stopped" ) return precondition_failed('hackathen is ended') template = hack_temp[1] if user_id > 0: expr = self.__check_expr_status(user_id, hackathon, template) if expr is not None: return self.__report_expr_status(expr) # new expr return self.__start_new_expr(hackathon, template, user_id)
def join_team(self, hackathon_id, team_name, user): """Join a team will create a record on user_team_rel table which status will be 0. :type hackathon_id: int :param hackathon_id: hackathon id :type team_name: str | unicode :param team_name: team name :type user: User :param user: the user to join a team :rtype: dict :return: if user already joined team or team not exist, return bad request. Else, return a dict of joined details. """ if self.db.find_first_object_by(UserTeamRel, hackathon_id=hackathon_id, user_id=g.user.id): return precondition_failed( "You have joined another team, please quit first.") team = self.__get_team_by_name(hackathon_id, team_name) if team: candidate = UserTeamRel(join_time=self.util.get_now(), update_time=self.util.get_now(), status=TeamMemberStatus.Init, hackathon_id=hackathon_id, user_id=user.id, team_id=team.id) self.db.add_object(candidate) return candidate.dic() else: return not_found("team not found !")
def kick_or_leave(self, operator, team_id, user_id): try: team = Team.objects(id=team_id, members__user=user_id).first() except ValidationError: return not_found() if not team: return not_found() mem = filter(lambda x: str(x.user.id) == user_id, team.members) assert len(mem) < 2 if not mem: return not_found() mem = mem[0] hackathon = team.hackathon user = mem.user if str(team.leader.id) == user_id: # if the user to be leaved or kicked is team leader return precondition_failed("leader cannot leave team") if str(operator.id) == user_id: # leave team team.members.remove(mem) team.save() self.create_default_team(hackathon, user) else: # kick somebody else self.__validate_team_permission(hackathon.id, team, operator) team.members.remove(mem) team.save() self.create_default_team(hackathon, user) return ok()
def test_create_hackathon_register_registration_not_begin(self, get_method): args = {'user_id': 1} hackathon = Hackathon(id=1, registration_start_time=self.get_now() + datetime.timedelta(seconds=30)) get_method.retrun_value = None self.assertEqual(self.register_manager.create_registration(hackathon, args), precondition_failed("hackathon registration not opened", friendly_message="报名尚未开始")) get_method.assert_called_once_with(1, 1)
def update_team(self, kwargs): """Update existing team information :type kwargs: dict :param kwargs: a dict to store update information for team :rtype: dict :return: updated team information in a dict """ team = self.__get_team_by_id(kwargs["id"]) if not team: return not_found("team not exists") # avoid duplicate team with same names if "name" in kwargs and kwargs["name"] != team.name: if self.__get_team_by_name(g.hackathon.id, kwargs["name"]): return precondition_failed("team with the same name exists already") self.__validate_team_permission(g.hackathon.id, team, g.user) # hackathon.modify(**update_items) # team.name = kwargs.get("name", team.name) # team.description = kwargs.get("description", team.description) # team.logo = kwargs.get("logo", team.logo) kwargs.pop("id", None) # id should not be included team.modify(**kwargs) team.update_time = self.util.get_now() team.save() return self.__team_detail(team)
def add_admin(self, args): """Add a new administrator on a hackathon :type args: dict :param args: http request body in json format :return hackathon response 'ok' if successfully added. 'not_found' if email is invalid or user not found. 'internal_server_error' if any other unexpected exception caught """ user = self.user_manager.get_user_by_email(args.get("email")) if user is None: return not_found("user not found") if self.register_manager.is_user_registered(user.id, g.hackathon): return precondition_failed("Cannot add a registered user as admin", friendly_message="该用户已报名参赛,不能再被选为裁判或管理员。请先取消其报名") try: ahl = self.db.find_first_object(AdminHackathonRel, AdminHackathonRel.user_id == user.id, AdminHackathonRel.hackathon_id == g.hackathon.id) if ahl is None: ahl = AdminHackathonRel( user_id=user.id, role_type=args.get("role_type", ADMIN_ROLE_TYPE.ADMIN), hackathon_id=g.hackathon.id, remarks=args.get("remarks"), create_time=self.util.get_now() ) self.db.add_object(ahl) return ok() except Exception as e: self.log.error(e) return internal_server_error("create admin failed")
def start_expr(self, hackathon_name, template_name, user_id): """ A user uses a template to start a experiment under a hackathon :param hackathon_name: :param template_name: :param user_id: :return: """ hack_temp = self.__check_template_status(hackathon_name, template_name) if hack_temp is None: return not_found('hackathon or template is not existed') hackathon = hack_temp[0] # if not self.register_manager.is_user_registered(user_id, hackathon): # return forbidden("user not registered or not approved") if hackathon.event_end_time < self.util.get_now(): self.log.warn("hackathon is ended. The expr starting process will be stopped") return precondition_failed('hackathen is ended') template = hack_temp[1] if user_id > 0: expr = self.__check_expr_status(user_id, hackathon, template) if expr is not None: return self.__report_expr_status(expr) # new expr return self.__start_new_expr(hackathon, template, user_id)
def create_team(self, kwargs): """Create new team by given args. user only allow to join or create 1 team. So if user joined or created team before, will be get failed when creating new team. :type kwargs: dict :param kwargs: a dict of required information to create new team :rtype: dict :return: created team information """ user_team_rel = self.__get_team_by_user(g.user.id, g.hackathon.id) if user_team_rel: self.log.debug( "fail to create team since user is already in some team.") return precondition_failed("you must leave the current team first") if "team_name" not in kwargs: return bad_request("Please provide a team name") # check team name to avoid duplicate name team_name = kwargs["team_name"] if self.__get_team_by_name(g.hackathon.id, team_name): return precondition_failed( "The team name is existed, please provide a new name") team = Team(name=team_name, description=kwargs.get("description"), git_project=kwargs.get("git_project"), logo=kwargs.get("logo"), create_time=self.util.get_now(), update_time=self.util.get_now(), leader_id=g.user.id, hackathon_id=g.hackathon.id) self.db.add_object(team) user_team_rel = UserTeamRel(join_time=self.util.get_now(), update_time=self.util.get_now(), status=TeamMemberStatus.Approved, hackathon_id=g.hackathon.id, user_id=g.user.id, team_id=team.id) self.db.add_object(user_team_rel) return team.dic()
def create_registration(self, hackathon, user, args): """Register hackathon for user Will add a new record in table UserRegistrationRel if precondition fulfilled """ self.log.debug("create_register: %r" % args) user_id = args['user_id'] check_login_provider = self.__is_user_hackathon_login_provider(user, hackathon) if check_login_provider["fail"]: return login_provider_error("hackathon registration not login provider", friendly_message="当前黑客松活动只是使用"+",".join(check_login_provider["provides"])+"账户才能报名", provides=",".join(check_login_provider["provides"])) if self.is_user_registered(user.id, hackathon): self.log.debug("user %d already registered on hackathon %d" % (user_id, hackathon.id)) return self.get_registration_detail(user, hackathon) if self.admin_manager.is_hackathon_admin(hackathon.id, user.id): return precondition_failed("administrator cannot register the hackathon", friendly_message="管理员或裁判不能报名") if hackathon.registration_start_time and hackathon.registration_start_time > self.util.get_now(): return precondition_failed("hackathon registration not opened", friendly_message="报名尚未开始") if hackathon.registration_end_time and hackathon.registration_end_time < self.util.get_now(): return precondition_failed("hackathon registration has ended", friendly_message="报名已经结束") if self.__is_hackathon_filled_up(hackathon): return precondition_failed("hackathon registers reach the upper threshold", friendly_message="报名人数已满") try: args["status"] = RGStatus.AUTO_PASSED if hackathon.is_auto_approve() else RGStatus.UNAUDIT args['create_time'] = self.util.get_now() user_hackathon_rel = self.db.add_object_kwargs(UserHackathonRel, **args).dic() # create a team as soon as user registration approved(auto or manually) if hackathon.is_auto_approve(): self.team_manager.create_default_team(hackathon, user) self.__update_register_stat(hackathon) return user_hackathon_rel except Exception as e: self.log.error(e) return internal_server_error("fail to create register")
def validate_created_args(self, hackathon, args): self.log.debug("create_register: %r" % args) user_id = args['user_id'] register = self.get_registration_by_user_and_hackathon(user_id, hackathon.id) if register is not None and register.deleted == 0: self.log.debug("user %d already registered on hackathon %d" % (user_id, hackathon.id)) return False, register.dic() if hackathon.registration_start_time > self.util.get_now(): return False, precondition_failed("hackathon registration not opened", friendly_message="报名尚未开始") if hackathon.registration_end_time < self.util.get_now(): return False, precondition_failed("hackathon registration has ended", friendly_message="报名已经结束") if not self.check_register_enrollment(hackathon): return False, precondition_failed("hackathon registers reach the upper threshold", friendly_message="报名人数已满") return True, ""
def test_create_hackathon_register_registration_already_finished(self, get_method): get_method.retrun_value = None args = {'user_id': 1} hackathon = Hackathon(id=1, registration_start_time=self.get_now() - datetime.timedelta(seconds=30), registration_end_time=self.get_now() - datetime.timedelta(seconds=30)) self.assertEqual(self.register_manager.create_registration(hackathon, args), precondition_failed("hackathon registration has ended", friendly_message="报名已经结束")) get_method.assert_called_once_with(1, 1)
def create_team(self, kwargs): """Create new team by given args. user only allow to join or create 1 team. So if user joined or created team before, will be get failed when creating new team. :type kwargs: dict :param kwargs: a dict of required information to create new team :rtype: dict :return: created team information """ user_team_rel = self.__get_team_by_user(g.user.id, g.hackathon.id) if user_team_rel: self.log.debug("fail to create team since user is already in some team.") return precondition_failed("you must leave the current team first") if "team_name" not in kwargs: return bad_request("Please provide a team name") # check team name to avoid duplicate name team_name = kwargs["team_name"] if self.__get_team_by_name(g.hackathon.id, team_name): return precondition_failed("The team name is existed, please provide a new name") team = Team(name=team_name, description=kwargs.get("description"), git_project=kwargs.get("git_project"), logo=kwargs.get("logo"), create_time=self.util.get_now(), update_time=self.util.get_now(), leader_id=g.user.id, hackathon_id=g.hackathon.id) self.db.add_object(team) user_team_rel = UserTeamRel(join_time=self.util.get_now(), update_time=self.util.get_now(), status=TeamMemberStatus.Approved, hackathon_id=g.hackathon.id, user_id=g.user.id, team_id=team.id) self.db.add_object(user_team_rel) return team.dic()
def test_validate_deleted_args_delete_creator(self): ahl = AdminHackathonRel(id=7, user_id=7, hackathon_id=7) hackathon = Hackathon(id=7, creator_id=7) db_adapter = Mock() db_adapter.find_first_object.side_effect = [ahl, hackathon] am = AdminManager(db_adapter) status, return_info = am.validate_deleted_args(1) self.assertFalse(status) self.assertEqual(return_info, precondition_failed("hackathon creator can not be deleted")) self.assertEqual(db_adapter.find_first_object.call_count, 2)
def test_create_hackathon_register_registration_not_begin( self, get_method): args = {'user_id': 1} hackathon = Hackathon(id=1, registration_start_time=self.get_now() + datetime.timedelta(seconds=30)) get_method.retrun_value = None self.assertEqual( self.register_manager.create_registration(hackathon, args), precondition_failed("hackathon registration not opened", friendly_message="报名尚未开始")) get_method.assert_called_once_with(1, 1)
def delete_template_from_team(self, template_id): """Delete template from current user's team Team should exist and current login user must be the leader """ team = self.__get_valid_team_by_user(g.user.id, g.hackathon.id) if not team: return precondition_failed("you don't join any team so you cannot add teamplate") if team.leader.id != g.user.id: return forbidden("team leader required") else: return self.hackathon_template_manager.delete_template_from_hackathon(template_id)
def validate_created_args(self, hackathon, args): self.log.debug("create_register: %r" % args) user_id = args['user_id'] register = self.get_registration_by_user_and_hackathon( user_id, hackathon.id) if register is not None and register.deleted == 0: self.log.debug("user %d already registered on hackathon %d" % (user_id, hackathon.id)) return False, register.dic() if hackathon.registration_start_time > self.util.get_now(): return False, precondition_failed( "hackathon registration not opened", friendly_message="报名尚未开始") if hackathon.registration_end_time < self.util.get_now(): return False, precondition_failed( "hackathon registration has ended", friendly_message="报名已经结束") if not self.check_register_enrollment(hackathon): return False, precondition_failed( "hackathon registers reach the upper threshold", friendly_message="报名人数已满") return True, ""
def test_create_hackathon_register_registration_already_finished( self, get_method): get_method.retrun_value = None args = {'user_id': 1} hackathon = Hackathon(id=1, registration_start_time=self.get_now() - datetime.timedelta(seconds=30), registration_end_time=self.get_now() - datetime.timedelta(seconds=30)) self.assertEqual( self.register_manager.create_registration(hackathon, args), precondition_failed("hackathon registration has ended", friendly_message="报名已经结束")) get_method.assert_called_once_with(1, 1)
def add_template_for_team(self, args): """Add template to team of the current user by template name template_id must be included in args. Current login user must have a team and HE must be its leader """ if "template_id" not in args: return bad_request("template id invalid") team = self.__get_valid_team_by_user(g.user.id, g.hackathon.id) if not team: return precondition_failed("you don't join any team so you cannot add teamplate") if team.leader.id != g.user.id: return forbidden("team leader required") else: return self.hackathon_template_manager.add_template_to_hackathon(args["template_id"])
def create_default_team(self, hackathon, user): """Create a default new team for user after registration. Use user name as team name by default. Append user id in case user name is duplicate """ user_team = self.__get_valid_team_by_user(user.id, hackathon.id) if user_team: self.log.debug("fail to create team since user is already in some team.") return precondition_failed("you must leave the current team first") team_name = self.__generate_team_name(hackathon, user) team_member = TeamMember(join_time=self.util.get_now(), status=TEAM_MEMBER_STATUS.APPROVED, user=user) team = Team(name=team_name, leader=user, logo=user.avatar_url, hackathon=hackathon, members=[team_member]) team.save() return team.dic()
def delete_admin(self, ahl_id): """Delete admin on a hackathon creator of the hackathon cannot be deleted. :returns ok() if succeeds or it's deleted before. precondition_failed if try to delete the creator """ ahl = self.db.find_first_object(AdminHackathonRel, AdminHackathonRel.id == ahl_id) if not ahl: return ok() hackathon = self.hackathon_manager.get_hackathon_by_id(ahl.hackathon_id) if hackathon and hackathon.creator_id == ahl.user_id: return precondition_failed("hackathon creator can not be deleted") self.db.delete_all_objects(AdminHackathonRel, AdminHackathonRel.id == ahl_id) return ok()
def delete_admin(self, user_hackathon_id): """Delete admin on a hackathon creator of the hackathon cannot be deleted. :returns ok() if succeeds or it's deleted before. precondition_failed if try to delete the creator """ user_hackathon = UserHackathon.objects(id=user_hackathon_id).first() if not user_hackathon: return ok() hackathon = user_hackathon.hackathon if hackathon and hackathon.creator == user_hackathon.user: return precondition_failed("hackathon creator can not be deleted") user_hackathon.delete() return ok()
def kick_or_leave(self, operator, team_id, user_id): rel = self.db.find_first_object_by(UserTeamRel, team_id=team_id, user_id=user_id) if not rel: return not_found() team = rel.team hackathon = rel.hackathon user = rel.user if team.leader_id == rel.user_id: # if the user to be leaved or kicked is team leader return precondition_failed("leader cannot leave team") if operator.id == rel.user_id: # leave team self.db.delete_object(rel) self.db.commit() self.create_default_team(rel.hackathon, rel.user) else: # kick somebody else self.__validate_team_permission(hackathon.id, team, operator) self.db.delete_object(rel) self.create_default_team(hackathon, user) return ok()
def delete_host_server(self, host_server_id): """ delete a docker host_server for a hackathon. :param hackathon_id: the id of a hackathon in DB :type hackathon_id: Integer :param host_server_id: the id of host_server in DB :type host_server_id: Integer :return: ok() if succeeds or this host_server doesn't exist precondition_failed() if there are still some containers running """ vm = self.db.find_first_object_by(DockerHostServer, id=host_server_id) if vm is None: self.log.warn('delete docker_host fail, not find hostserver_id:' + host_server_id) return ok() if not vm.container_count == 0: return precondition_failed("", "fail to delete: there are some containers running in this server") self.db.delete_object(vm) return ok()
def delete_admin(self, ahl_id): """Delete admin on a hackathon creator of the hackathon cannot be deleted. :returns ok() if succeeds or it's deleted before. precondition_failed if try to delete the creator """ ahl = self.db.find_first_object(AdminHackathonRel, AdminHackathonRel.id == ahl_id) if not ahl: return ok() hackathon = self.hackathon_manager.get_hackathon_by_id( ahl.hackathon_id) if hackathon and hackathon.creator_id == ahl.user_id: return precondition_failed("hackathon creator can not be deleted") self.db.delete_all_objects(AdminHackathonRel, AdminHackathonRel.id == ahl_id) return ok()
def grant_award_to_team(self, hackathon, context): team = self.__get_team_by_id(context.team_id) if not team: return not_found("team not found") award = [a for a in hackathon.awards if str(a.id) == context.award_id] assert len(award) < 2 if not award: return not_found("award not found") award = award[0] if team.hackathon.id != hackathon.id: return precondition_failed("hackathon doesn't match") team_award = [a for a in team.awards if str(a) == context.award_id] assert len(team_award) < 2 if not team_award: team.awards.append(uuid.UUID(context.award_id)) team.save() return self.__award_with_detail(context.award_id)
def update_team(self, kwargs): """Update existing team information :type kwargs: dict :param kwargs: a dict to store update information for team :rtype: dict :return: updated team information in a dict """ team = self.__get_team_by_id(kwargs["id"]) if not team: return not_found("team not exists") # avoid duplicate team with same names if "name" in kwargs and kwargs["name"] != team.name: if self.__get_team_by_name(g.hackathon.id, kwargs["name"]): return precondition_failed( "team with the same name exists already") self.__validate_team_permission(g.hackathon.id, team, g.user) # hackathon.modify(**update_items) # team.name = kwargs.get("name", team.name) # team.description = kwargs.get("description", team.description) # team.logo = kwargs.get("logo", team.logo) kwargs.pop('id', None) # id should not be included team.modify(**kwargs) team.update_time = self.util.get_now() team.save() if "dev_plan" in kwargs and kwargs["dev_plan"] and not kwargs["dev_plan"] == "" \ and team.hackathon.config.get(HACKATHON_CONFIG.DEV_PLAN_REQUIRED, False): t = threading.Thread(target=self.__email_notify_dev_plan_submitted, args=(team, )) t.setDaemon(True) t.start() return self.__team_detail(team)
def add_admin(self, args): """Add a new administrator on a hackathon :type args: dict :param args: http request body in json format :return hackathon response 'ok' if successfully added. 'not_found' if email is invalid or user not found. 'internal_server_error' if any other unexpected exception caught """ user = self.user_manager.get_user_by_id(args.get("id")) if user is None: return not_found("user not found") if self.register_manager.is_user_registered(user.id, g.hackathon): return precondition_failed( "Cannot add a registered user as admin", friendly_message="该用户已报名参赛,不能再被选为裁判或管理员。请先取消其报名") try: user_hackathon = UserHackathon.objects( user=user.id, hackathon=g.hackathon.id).first() if user_hackathon is None: uhl = UserHackathon(user=user, hackathon=g.hackathon, role=args.get("role"), status=HACK_USER_STATUS.AUTO_PASSED, remark=args.get("remark")) uhl.save() else: user_hackathon.role = args.get("role") user_hackathon.remark = args.get("remark") user_hackathon.save() return ok() except Exception as e: self.log.error(e) return internal_server_error("create admin failed")
def add_admin(self, args): """Add a new administrator on a hackathon :type args: dict :param args: http request body in json format :return hackathon response 'ok' if successfully added. 'not_found' if email is invalid or user not found. 'internal_server_error' if any other unexpected exception caught """ user = self.user_manager.get_user_by_id(args.get("id")) if user is None: return not_found("user not found") if self.register_manager.is_user_registered(user.id, g.hackathon): return precondition_failed("Cannot add a registered user as admin", friendly_message="该用户已报名参赛,不能再被选为裁判或管理员。请先取消其报名") try: user_hackathon = UserHackathon.objects(user=user.id, hackathon=g.hackathon.id).first() if user_hackathon is None: uhl = UserHackathon( user=user, hackathon=g.hackathon, role=args.get("role"), status=HACK_USER_STATUS.AUTO_PASSED, remark=args.get("remark") ) uhl.save() else: user_hackathon.role = args.get("role") user_hackathon.remark = args.get("remark") user_hackathon.save() return ok() except Exception as e: self.log.error(e) return internal_server_error("create admin failed")
def grant_award_to_team(self, hackathon, context): team = self.__get_team_by_id(context.team_id) if not team: return not_found("team not found") award = filter(lambda a: str(a.id) == context.award_id, hackathon.awards) assert len(award) < 2 if not award: return not_found("award not found") award = award[0] if team.hackathon.id != hackathon.id: return precondition_failed("hackathon doesn't match") team_award = filter(lambda a: str(a) == context.award_id, team.awards) assert len(team_award) < 2 if not team_award: team.awards.append(uuid.UUID(context.award_id)) team.save() return self.__award_with_detail(context.award_id)
def update_team(self, kwargs): """Update existing team information :type kwargs: dict :param kwargs: a dict to store update information for team :rtype: dict :return: updated team information in a dict """ team = self.__get_team_by_id(kwargs["id"]) if not team: return not_found("team not exists") # avoid duplicate team with same names if "name" in kwargs and kwargs["name"] != team.name: if self.__get_team_by_name(g.hackathon.id, kwargs["name"]): return precondition_failed("team with the same name exists already") self.__validate_team_permission(g.hackathon.id, team, g.user) # hackathon.modify(**update_items) # team.name = kwargs.get("name", team.name) # team.description = kwargs.get("description", team.description) # team.logo = kwargs.get("logo", team.logo) kwargs.pop('id', None) # id should not be included team.modify(**kwargs) team.update_time = self.util.get_now() team.save() if "dev_plan" in kwargs and kwargs["dev_plan"] and not kwargs["dev_plan"] == "" \ and team.hackathon.config.get(HACKATHON_CONFIG.DEV_PLAN_REQUIRED, False): t = threading.Thread(target=self.__email_notify_dev_plan_submitted, args=(team,)) t.setDaemon(True) t.start() return self.__team_detail(team)
def add_admin(self, args): """Add a new administrator on a hackathon :type args: dict :param args: http request body in json format :return hackathon response 'ok' if successfully added. 'not_found' if email is invalid or user not found. 'internal_server_error' if any other unexpected exception caught """ user = self.user_manager.get_user_by_id(args.get("id")) if user is None: return not_found("user not found") if self.register_manager.is_user_registered(user.id, g.hackathon): return precondition_failed( "Cannot add a registered user as admin", friendly_message="该用户已报名参赛,不能再被选为裁判或管理员。请先取消其报名") try: ahl = self.db.find_first_object( AdminHackathonRel, AdminHackathonRel.user_id == user.id, AdminHackathonRel.hackathon_id == g.hackathon.id) if ahl is None: ahl = AdminHackathonRel(user_id=user.id, role_type=args.get( "role_type", ADMIN_ROLE_TYPE.ADMIN), hackathon_id=g.hackathon.id, remarks=args.get("remarks"), create_time=self.util.get_now()) self.db.add_object(ahl) return ok() except Exception as e: self.log.error(e) return internal_server_error("create admin failed")
def update_team_member_status(self, operator, team_id, user_id, status): """ update user's status on selected team. if current user doesn't have permission, return bad request. Else, update user's status :type status: int :param status: the status of the team member, see TEAM_MEMBER_STATUS in constants.py :rtype: bool :return: if update success, return ok. if not , return bad request. """ team = self.__get_team_by_id(team_id) if not team: return not_found() mem = [x for x in team.members if str(x.user.id) == user_id] assert len(mem) < 2 if not mem: return not_found() mem = mem[0] # #NOTE1# we have to re-check this here # because of this situation: # A is in a single-person team TeamA, and request join TeamB # after that, C join TeamA and now TeamA has two members, # this is not allowed when status == TEAM_MEMBER_STATUS.APPROVED cur_team = self.__get_valid_team_by_user(mem.user.id, team.hackathon.id) if cur_team and cur_team.members.count() > 1: return precondition_failed( "Team leader cannot join another team for team member count greater than 1" ) self.__validate_team_permission(team.hackathon.id, team, operator) if mem.user.id == team.leader.id: return precondition_failed("cannot update status of team leader") if status == TEAM_MEMBER_STATUS.APPROVED: # disable previous team first # NOTE: # Do we also have to delete status that is not TEAM_MEMBER_STATUS.APPROVED? # i.e., if A request join both TeamB and TeamC, TeamC approve join first, then TeamB approved, # this will cause A leave TeamB and join TeamC. # is this the desired behaviour? Team.objects(hackathon=team.hackathon.id).update( __raw__={ "$pull": { "members": { "user": user_id, "status": TEAM_MEMBER_STATUS.APPROVED } } }) # because only team leader with single team can make join request # so we don't have to make default team for other members in this team # we make the check in #NOTE1# so this is always true Team.objects(hackathon=team.hackathon.id, leader=mem.user.id).delete() mem.status = TEAM_MEMBER_STATUS.APPROVED mem.update_time = self.util.get_now() team.save() return ok("approved") if status == TEAM_MEMBER_STATUS.DENIED: user = mem.user hackathon = team.hackathon team.members.remove(mem) team.save() self.create_default_team(hackathon, user) return ok( "Your request has been denied, please rejoin another team.")