def quit_team_forcedly(self, team, user): """ The operator(admin or superadmin) forces a user(team leader or other members) to quit a team. If the user is the only member of the team, the team will be deleted. Else if the user is the leader of a team with several members, the team will be decomposed into several new teams. Else if the user is not the leader of a team with several members, just the user quits the team. :rtype: bool :return: if dismiss success, return ok. if not ,return bad request. """ # here we don't check whether the operator has the permission, if not team.members or len(team.members) == 0: self.log.warn("this team doesn't have any members") return ok() member_users = [m.user for m in team.members if m.status == TEAM_MEMBER_STATUS.APPROVED] num_team_members = len(member_users) hackathon = team.hackathon if num_team_members > 1: if team.leader == user: team.delete() for u in member_users: if u.id != user.id: self.create_default_team(hackathon, u) else: Team.objects(id=team.id).update_one(pull__members__user=user) else: # num_team_members == 1 team.delete() return ok()
def send_email_azure(self, kwargs): # team information team = self.__get_team_by_id(kwargs["id"]) if not team: return not_found("team not exists") azure = team.azure if not azure.strip(): if Azure.objects(status="0").count() == 0: return ok("请联系管理员.") azure_info = Azure.objects(status="0").first() else: azure_info = Azure.objects(account=azure).first() if not azure_info: return ok("请联系管理员!") primary_emails = [] for i in xrange(0, len(team.members)): mem = team.members[i] resp = self.user_manager.user_display_info(mem.user) primary_emails.append(resp['emails'][0]['email']) Azure.objects(account=azure_info.account).update_one(status="1") Team.objects(id=team.id).update_one(azure=azure_info.account) sender = '' email_title = '' email_content = '' return self.util.send_emails(sender, primary_emails, email_title, email_content)
def delete_hackathon_award(self, hackathon, award_id): award = hackathon.awards.get(id=award_id) hackathon.update(pull__awards=award) hackathon.update_time = self.util.get_now() hackathon.save() # delete granted award in teams award_uuid = uuid.UUID(award_id) Team.objects(hackathon=hackathon, awards=award_uuid).update(pull__awards=award_uuid) return ok()
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 __get_hackathon_detail(self, hackathon, user=None): """Return hackathon info as well as its details including configs, stat, organizers, like if user logon""" detail = hackathon.dic() detail["stat"] = {"register": 0, "like": 0} for stat in HackathonStat.objects(hackathon=hackathon): if stat.type == HACKATHON_STAT.REGISTER: detail["stat"]["register"] = stat.count elif stat.type == HACKATHON_STAT.LIKE: detail["stat"]["like"] = stat.count if user: user_hackathon = UserHackathon.objects(hackathon=hackathon, user=user).first() if user_hackathon and user_hackathon.like: detail['like'] = user_hackathon.like detail["user"] = self.user_manager.user_display_info(user) detail["user"]["is_admin"] = user.is_super or ( user_hackathon and user_hackathon.role == HACK_USER_TYPE.ADMIN) # TODO: we need to review those items one by one to decide the API output # asset = self.db.find_all_objects_by(UserHackathonAsset, user_id=user.id, hackathon_id=hackathon.id) # if asset: # detail["asset"] = [o.dic() for o in asset] if user_hackathon and user_hackathon.role == HACK_USER_TYPE.COMPETITOR: detail["registration"] = user_hackathon.dic() team = Team.objects(hackathon=hackathon, members__user=user).first() if team: detail["team"] = team.dic() return detail
def get_hackathon_team_list(self, hackathon_id, name=None, number=None): """Get the team list of selected hackathon :type hackathon_id: string or object_id :param hackathon_id: hackathon id :type name: str|unicode :param name: name of team. optional :type number: int :param number: querying condition, return number of teams :rtype: list :return: a list of team filter by name and number on selected hackathon """ query = Q(hackathon=hackathon_id) if name is not None: query &= Q(name__icontains=name) try: teams = Team.objects(query).order_by('name')[:number] except ValidationError: return [] # check whether it's anonymous user or not user = None if self.user_manager.validate_login(): user = g.user return [self.__team_detail(x, user) for x in teams]
def get_hackathon_list(self, args): # get values from request's QueryString page = int(args.get("page", 1)) per_page = int(args.get("per_page", 20)) order_by = args.get("order_by", "create_time") status = args.get("status") name = args.get("name") # build query by search conditions and order_by status_filter = Q() name_filter = Q() condition_filter = Q() order_by_condition = '-id' if status: status_filter = Q(status=status) if name: name_filter = Q(name__contains=name) if order_by == 'create_time': # 最新发布 order_by_condition = '-create_time' elif order_by == 'event_start_time': # 即将开始 order_by_condition = '-event_start_time' elif order_by == 'registered_users_num': # 人气热点 # hackathons with zero registered users would not be shown. hot_hackathon_stat = HackathonStat.objects( type=HACKATHON_STAT.REGISTER, count__gt=0).order_by('-count') hot_hackathon_list = [ stat.hackathon.id for stat in hot_hackathon_stat ] condition_filter = Q(id__in=hot_hackathon_list) else: order_by_condition = '-id' # perform db query with pagination pagination = Hackathon.objects(status_filter & name_filter & condition_filter).order_by( order_by_condition).paginate( page, per_page) hackathon_list = pagination.items hackathon_stat = HackathonStat.objects(hackathon__in=hackathon_list) user = None user_hackathon = [] team = [] if self.user_manager.validate_login(): user = g.user user_hackathon = UserHackathon.objects( user=user, hackathon__in=hackathon_list) team = Team.objects(members__user=user, hackathon__in=hackathon_list) def func(hackathon): return self.__fill_hackathon_detail(hackathon, user, hackathon_stat, user_hackathon, team) # return serializable items as well as total count return self.util.paginate(pagination, func)
def check_notice_and_set_read_if_necessary(self, id): hackathon_notice = HackathonNotice.objects(id=id).first() if hackathon_notice: user = g.user if not user or user.id != hackathon_notice.receiver.id: # not the user return ok() hackathon_notice.is_read = True if hackathon_notice.event == HACK_NOTICE_EVENT.HACK_PLAN: # set is_read = True if dev_plan is complete user = hackathon_notice.receiver hackathon = hackathon_notice.hackathon team = Team.objects(members__user=user, hackathon=hackathon).first() if team: if not team.dev_plan: # the dev_plan isn't submitted hackathon_notice.is_read = False elif hackathon.config.get( HACKATHON_CONFIG.REAL_NAME_AUTH_21V, False): self.create_hackathon_notice( hackathon.id, HACK_NOTICE_EVENT.HACK_REGISTER_AZURE, HACK_NOTICE_CATEGORY.HACKATHON, {'receiver': user}) hackathon_notice.save() return ok()
def __get_hackathon_detail(self, hackathon, user=None): """Return hackathon info as well as its details including configs, stat, organizers, like if user logon""" detail = hackathon.dic() detail["stat"] = { "register": 0, "like": 0} for stat in HackathonStat.objects(hackathon=hackathon): if stat.type == HACKATHON_STAT.REGISTER: detail["stat"]["register"] = stat.count elif stat.type == HACKATHON_STAT.LIKE: detail["stat"]["like"] = stat.count if user: user_hackathon = UserHackathon.objects(hackathon=hackathon, user=user).first() if user_hackathon and user_hackathon.like: detail['like'] = user_hackathon.like detail["user"] = self.user_manager.user_display_info(user) detail["user"]["is_admin"] = user.is_super or ( user_hackathon and user_hackathon.role == HACK_USER_TYPE.ADMIN) # TODO: we need to review those items one by one to decide the API output # asset = self.db.find_all_objects_by(UserHackathonAsset, user_id=user.id, hackathon_id=hackathon.id) # if asset: # detail["asset"] = [o.dic() for o in asset] if user_hackathon and user_hackathon.role == HACK_USER_TYPE.COMPETITOR: detail["registration"] = user_hackathon.dic() team = Team.objects(hackathon=hackathon, members__user=user).first() if team: detail["team"] = team.dic() return detail
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 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 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 get_team_show_list_by_user(self, user_id): teams = Team.objects(members__match={"user": user_id, "status": TEAM_MEMBER_STATUS.APPROVED}).all() def get_team_show_detail(team): dic = self.__team_detail(team) dic["hackathon"] = team.hackathon.dic() return dic return [get_team_show_detail(team) for team in teams if not len(team.works) == 0]
def get_granted_awards(self, hackathon): awards = [] for team in Team.objects(hackathon=hackathon): awards += team.awards awards = [self.__award_with_detail(r) for r in awards] awards.sort(lambda a, b: (b.level - a.level) * 10 + int(a.create_time < b.create_time)) return awards
def get_hackathon_team_list(self, hackathon_id, name=None, number=None): """Get the team list of selected hackathon :type hackathon_id: string or object_id :param hackathon_id: hackathon id :type name: str|unicode :param name: name of team. optional :type number: int :param number: querying condition, return number of teams :rtype: list :return: a list of team filter by name and number on selected hackathon """ query = Q(hackathon=hackathon_id) if name is not None: query &= Q(name__icontains=name) try: teams = Team.objects(query).order_by('name')[:number] except ValidationError: return [] # check whether it's anonymous user or not user = None if self.user_manager.validate_token(): user = g.user def get_team(team): teamDic = team.dic() teamDic['leader'] = { 'id': str(team.leader.id), 'name': team.leader.name, 'nickname': team.leader.nickname, 'avatar_url': team.leader.avatar_url } teamDic['cover'] = teamDic.get('cover', '') teamDic['project_name'] = teamDic.get('project_name', '') teamDic['dev_plan'] = teamDic.get('dev_plan', '') teamDic['works'] = teamDic.get('works', '') [ teamDic.pop(key, None) for key in ['assets', 'azure_keys', 'scores', 'templates', 'hackathon'] ] teamDic["member_count"] = team.members.filter( status=TEAM_MEMBER_STATUS.APPROVED).count() def sub(t): m = to_dic(t) m["user"] = self.user_manager.user_display_info(t.user) return m teamDic["members"] = [sub(t) for t in team.members] return teamDic return [get_team(x) for x in teams]
def get_granted_awards(self, hackathon): awards = [] for team in Team.objects(hackathon=hackathon): awards += team.awards awards = [self.__award_with_detail(r) for r in awards] awards.sort(lambda a, b: b["level"] - a["level"]) return awards
def __get_user_teams(self, user_id): """Get all teams of specific and related hackathon display info :type user_id: int :param user_id: User id to get teams. Cannot be None :rtype: list :return list of all teams as well as hackathon info """ return Team.objects(members__user=user_id).all()
def get_team_source_code(self, team_id): try: team = Team.objects(id=team_id, works__type=TEAM_SHOW_TYPE.SOURCE_CODE) except ValidationError: return None if not team: return None return filter(lambda w: w.type == TEAM_SHOW_TYPE.SOURCE_CODE, team.works)[0]
def get_team_show_list_by_user(self, user_id): teams = Team.objects(members__match={ "user": user_id, "status": TEAM_MEMBER_STATUS.APPROVED}).all() def get_team_show_detail(team): dic = self.__team_detail(team) dic["hackathon"] = team.hackathon.dic() return dic return [get_team_show_detail(team) for team in teams if not len(team.works) == 0]
def get_hackathon_team_list(self, hackathon_id, name=None, number=None): """Get the team list of selected hackathon :type hackathon_id: string or object_id :param hackathon_id: hackathon id :type name: str|unicode :param name: name of team. optional :type number: int :param number: querying condition, return number of teams :rtype: list :return: a list of team filter by name and number on selected hackathon """ query = Q(hackathon=hackathon_id) if name is not None: query &= Q(name__icontains=name) try: teams = Team.objects(query).order_by('name')[:number] except ValidationError: return [] # check whether it's anonymous user or not user = None if self.user_manager.validate_login(): user = g.user def get_team(team): teamDic = team.dic() teamDic['leader'] = { 'id': str(team.leader.id), 'name': team.leader.name, 'nickname': team.leader.nickname, 'avatar_url': team.leader.avatar_url } teamDic['cover'] = teamDic.get('cover', '') teamDic['project_name'] = teamDic.get('project_name', '') teamDic['dev_plan'] = teamDic.get('dev_plan', '') teamDic['works'] = teamDic.get('works', '') [teamDic.pop(key, None) for key in ['assets', 'awards', 'azure_keys', 'scores', 'templates', 'hackathon']] teamDic["member_count"] = team.members.filter(status=TEAM_MEMBER_STATUS.APPROVED).count() def sub(t): m = to_dic(t) m["user"] = self.user_manager.user_display_info(t.user) return m teamDic["members"] = [sub(t) for t in team.members] return teamDic return [get_team(x) for x in teams]
def get_all_granted_awards(self, limit): teams = Team.objects().all() teams_with_awards = [team for team in teams if not team.awards == []] teams_with_awards.sort(key=lambda t: ( t.hackathon.id, Hackathon.objects(id=t.hackathon.id, awards__id=t.awards[0]).first().awards.get(id=t.awards[0]).level ), reverse=True) # sort by hackathon and then sort by award level. teams_with_awards = teams_with_awards[0: int(limit)] return [self.__get_hackathon_and_show_detail(team) for team in teams_with_awards]
def get_granted_awards(self, hackathon): awards = [] team_id_with_awards = [] for team in Team.objects(hackathon=hackathon): awards += team.awards if not len(team.awards) == 0: team_id_with_awards.append(team.id) awards = [self.__award_with_detail(r) for r in awards] awards.sort(lambda a, b: b["level"] - a["level"]) # find teams who are granted these awards for award in awards: award["team"] = [] for team_id in team_id_with_awards: team = Team.objects(id=team_id).first() if uuid.UUID(award["id"]) in team.awards: award["team"].append(team.dic()) # len(awards) is equal to the number of all awards granted, so it's duplicated, remove duplicated items in JS. return awards
def get_team_source_code(self, team_id): try: team = Team.objects(id=team_id, works__type=TEAM_SHOW_TYPE.SOURCE_CODE) except ValidationError: return None if not team: return None return [w for w in team.works if w.type == TEAM_SHOW_TYPE.SOURCE_CODE][0]
def __get_valid_team_by_user(self, user_id, hackathon_id): """Get valid Team(Mongo-document) by user and hackathon "valid" means user is approved. There might be other records where status=Init Since foreign keys are defined in Team, one can access team or user through the return result directly :rtype: Team :return instance of Team """ return Team.objects( hackathon=hackathon_id, members__match={"user": user_id, "status": TEAM_MEMBER_STATUS.APPROVED} ).first()
def get_hackathon_list(self, args): # get values from request's QueryString page = int(args.get("page", 1)) per_page = int(args.get("per_page", 20)) order_by = args.get("order_by", "create_time") status = args.get("status") name = args.get("name") # build query by search conditions and order_by status_filter = Q() name_filter = Q() condition_filter = Q() order_by_condition = '-id' if status: status_filter = Q(status=status) if name: name_filter = Q(name__contains=name) if order_by == 'create_time': # 最新发布 order_by_condition = '-create_time' elif order_by == 'event_start_time': # 即将开始 order_by_condition = '-event_start_time' elif order_by == 'registered_users_num': # 人气热点 # hackathons with zero registered users would not be shown. hot_hackathon_stat = HackathonStat.objects(type=HACKATHON_STAT.REGISTER, count__gt=0).order_by('-count') hot_hackathon_list = [stat.hackathon.id for stat in hot_hackathon_stat] condition_filter = Q(id__in=hot_hackathon_list) else: order_by_condition = '-id' # perform db query with pagination pagination = Hackathon.objects(status_filter & name_filter & condition_filter).order_by( order_by_condition).paginate(page, per_page) hackathon_list = pagination.items hackathon_stat = HackathonStat.objects(hackathon__in=hackathon_list) user = None user_hackathon = [] team = [] if self.user_manager.validate_login(): user = g.user user_hackathon = UserHackathon.objects(user=user, hackathon__in=hackathon_list) team = Team.objects(members__user=user, hackathon__in=hackathon_list) def func(hackathon): return self.__fill_hackathon_detail(hackathon, user, hackathon_stat, user_hackathon, team) # return serializable items as well as total count return self.util.paginate(pagination, func)
def __get_valid_team_by_user(self, user_id, hackathon_id): """Get valid Team(Mongo-document) by user and hackathon "valid" means user is approved. There might be other records where status=Init Since foreign keys are defined in Team, one can access team or user through the return result directly :rtype: Team :return instance of Team """ return Team.objects(hackathon=hackathon_id, members__match={ "user": user_id, "status": TEAM_MEMBER_STATUS.APPROVED }).first()
def delete_team_show(self, user, show_id): try: team = Team.objects(works__id=show_id).first() except (ValidationError, ValueError): return not_found("wrong id format") if team: self.__validate_team_permission(team.hackathon.id, team, user) for i in range(len(team.works)): if str(team.works[i].id) == show_id: team.works.pop(i) team.save() break return ok()
def delete_team_show(self, user, show_id): try: team = Team.objects(works__id=show_id).first() except (ValidationError, ValueError): return not_found("wrong id format") if team: self.__validate_team_permission(team.hackathon.id, team, user) for i in xrange(len(team.works)): if str(team.works[i].id) == show_id: team.works.pop(i) team.save() break return ok()
def __get_team_by_name(self, hackathon_id, team_name): """ get user's team basic information stored on table 'team' based on team name :type hackathon_id: int :param hackathon_id: hackathon id for the team :type team_name: str|unicode :param team_name: name of the team :rtype: Team :return: instance of Team if team found otherwise None """ try: return Team.objects(hackathon=hackathon_id, name=team_name).first() except ValidationError: return None
def check_notice_and_set_read_if_necessary(self, id): hackathon_notice = HackathonNotice.objects(id=id).first() if hackathon_notice: user = g.user if not user or user.id != hackathon_notice.receiver.id: # not the user return ok() hackathon_notice.is_read = True if hackathon_notice.event == HACK_NOTICE_EVENT.HACK_PLAN: # set is_read = True if dev_plan is complete user = hackathon_notice.receiver hackathon = hackathon_notice.hackathon team = Team.objects(members__user=user, hackathon=hackathon).first() if team: if not team.dev_plan: # the dev_plan isn't submitted hackathon_notice.is_read = False hackathon_notice.save() return ok()
def get_hackathon_show_list(self, hackathon_id, show_type=None, limit=6): query = Q(hackathon=hackathon_id) if show_type is not None: query &= Q(works__type=int(show_type)) works = [] for team in Team.objects(query).filter(works__1__exists=True).order_by( 'update_time', '-age')[:limit]: teamDic = team.dic() teamDic['leader'] = { 'id': str(team.leader.id), 'name': team.leader.name, 'nickname': team.leader.nickname, 'avatar_url': team.leader.avatar_url } teamDic['cover'] = teamDic.get('cover', '') teamDic['project_name'] = teamDic.get('project_name', '') teamDic['dev_plan'] = teamDic.get('dev_plan', '') [ teamDic.pop(key, None) for key in [ 'assets', 'awards', 'azure_keys', 'scores', 'templates', 'members' ] ] # # teamDic['works'] = [] # # for work in team.works: # teamDic['works'].append(to_dic(work)) works.append(teamDic) # works.sort(lambda a, b: int(b["create_time"] - a["create_time"])) # def proc_work(w): # w.pop("create_time") # w["id"] = str(w["id"]) # w["team_id"] = str(w["team_id"]) # w["hackathon_id"] = str(w["hackathon_id"]) # return w return works
def get_team_members(self, team_id): """Get team member list of specific team :rtype: dict :return: team's information and team's members list if team is found otherwise not_found() """ try: team = Team.objects(id=team_id).first() except ValidationError: return None if not team: return None def sub(t): m = to_dic(t) m["user"] = self.user_manager.user_display_info(t.user) return m return [sub(t) for t in team.members]
def check_notice_and_set_read_if_necessary(self, id): hackathon_notice = HackathonNotice.objects(id=id).first() if hackathon_notice: user = g.user if not user or user.id != hackathon_notice.receiver.id: # not the user return ok() hackathon_notice.is_read = True if hackathon_notice.event == HACK_NOTICE_EVENT.HACK_PLAN: # set is_read = True if dev_plan is complete user = hackathon_notice.receiver hackathon = hackathon_notice.hackathon team = Team.objects(members__user=user, hackathon=hackathon).first() if team: if not team.dev_plan: # the dev_plan isn't submitted hackathon_notice.is_read = False elif hackathon.config.get(HACKATHON_CONFIG.REAL_NAME_AUTH_21V, False): self.create_hackathon_notice(hackathon.id, HACK_NOTICE_EVENT.HACK_REGISTER_AZURE, HACK_NOTICE_CATEGORY.HACKATHON, {'receiver': user}) hackathon_notice.save() return ok()
def get_hackathon_show_list(self, hackathon_id, show_type=None, limit=6): query = Q(hackathon=hackathon_id) if show_type is not None: query &= Q(works__type=int(show_type)) works = [] for team in Team.objects(query): cur_works = [] uris = [] for work in team.works: cur_works.append({ "name": team.name, "description": team.description, "logo": team.logo, "id": work.id, "note": work.description, "team_id": team.id, "hackathon_id": hackathon_id, "create_time": time.mktime(work.create_time.timetuple())}) uris.append((work.uri, work.type)) uri = ",".join([uri + ':::' + str(type) for uri, type in uris]) for work in cur_works: work["uri"] = uri works += cur_works works.sort(lambda a, b: int(b["create_time"] - a["create_time"])) def proc_work(w): w.pop("create_time") w["id"] = str(w["id"]) w["team_id"] = str(w["team_id"]) w["hackathon_id"] = str(w["hackathon_id"]) return w return [proc_work(x) for x in works[:limit]]
def get_hackathon_show_list(self, hackathon_id, show_type=None, limit=6): query = Q(hackathon=hackathon_id) if show_type is not None: query &= Q(works__type=int(show_type)) works = [] for team in Team.objects(query).filter(works__1__exists=True).order_by('update_time', '-age')[:limit]: teamDic = team.dic() teamDic['leader'] = { 'id': str(team.leader.id), 'name': team.leader.name, 'nickname': team.leader.nickname, 'avatar_url': team.leader.avatar_url } teamDic['cover'] = teamDic.get('cover', '') teamDic['project_name'] = teamDic.get('project_name', '') teamDic['dev_plan'] = teamDic.get('dev_plan', '') [teamDic.pop(key, None) for key in ['assets', 'awards', 'azure_keys', 'scores', 'templates', 'members']] # # teamDic['works'] = [] # # for work in team.works: # teamDic['works'].append(to_dic(work)) works.append(teamDic) # works.sort(lambda a, b: int(b["create_time"] - a["create_time"])) # def proc_work(w): # w.pop("create_time") # w["id"] = str(w["id"]) # w["team_id"] = str(w["team_id"]) # w["hackathon_id"] = str(w["hackathon_id"]) # return w return works
def get_hackathon_show_list(self, hackathon_id, show_type=None, limit=6): query = Q(hackathon=hackathon_id) if show_type is not None: query &= Q(works__type=int(show_type)) works = [] for team in Team.objects(query).filter(works__1__exists=True).order_by("update_time", "-age")[:limit]: teamDic = team.dic() teamDic["leader"] = { "id": str(team.leader.id), "name": team.leader.name, "nickname": team.leader.nickname, "avatar_url": team.leader.avatar_url, } teamDic["cover"] = teamDic.get("cover", "") teamDic["project_name"] = teamDic.get("project_name", "") teamDic["dev_plan"] = teamDic.get("dev_plan", "") [teamDic.pop(key, None) for key in ["assets", "awards", "azure_keys", "scores", "templates", "members"]] # # teamDic['works'] = [] # # for work in team.works: # teamDic['works'].append(to_dic(work)) works.append(teamDic) # works.sort(lambda a, b: int(b["create_time"] - a["create_time"])) # def proc_work(w): # w.pop("create_time") # w["id"] = str(w["id"]) # w["team_id"] = str(w["team_id"]) # w["hackathon_id"] = str(w["hackathon_id"]) # return w return works
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 = filter(lambda x: str(x.user.id) == user_id, team.members) 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.")
def get_team_by_user_and_hackathon(self, user, hackathon): team = Team.objects(hackathon=hackathon, members__user=user).first() return team
def __get_team_by_id(self, team_id): """Get team by its primary key""" try: return Team.objects(id=team_id).first() except ValidationError: return None
def __generate_team_name(self, hackathon, user): """Generate a default team name by user name. It can be updated later by team leader""" team_name = user.name if Team.objects(hackathon=hackathon, name=team_name).first(): team_name = "%s (%s)" % (user.name, user.id) return team_name
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.")