def __create_hackathon(self, creator, context):
        """Insert hackathon and creator(admin of course) to database

        We enforce that default config are used during the creation

        :type context: Context
        :param context: context of the args to create a new hackathon

        :rtype: Hackathon
        :return hackathon instance
        """

        new_hack = Hackathon(
            name=context.name,
            display_name=context.display_name,
            ribbon=context.get("ribbon"),
            description=context.get("description"),
            short_description=context.get("short_description"),
            location=context.get("location"),
            banners=context.get("banners", []),
            status=HACK_STATUS.INIT,
            creator=creator,
            type=context.get("type", HACK_TYPE.HACKATHON),
            config=context.get("config", Context()).to_dict(),
            tags=context.get("tags", []),
            event_start_time=context.get("event_start_time"),
            event_end_time=context.get("event_end_time"),
            registration_start_time=context.get("registration_start_time"),
            registration_end_time=context.get("registration_end_time"),
            judge_start_time=context.get("judge_start_time"),
            judge_end_time=context.get("judge_end_time")
        )

        # basic xss prevention
        if new_hack.description:  # case None type
            new_hack.description = self.cleaner.clean_html(new_hack.description)

        # insert into table hackathon
        new_hack.save()

        # add the current login user as admin and creator
        try:
            admin = UserHackathon(user=creator,
                                  hackathon=new_hack,
                                  role=HACK_USER_TYPE.ADMIN,
                                  status=HACK_USER_STATUS.AUTO_PASSED,
                                  remark='creator')
            admin.save()
        except Exception as ex:
            # TODO: send out a email to remind administrator to deal with this problems
            self.log.error(ex)
            raise InternalServerError("fail to create the default administrator")

        return new_hack
Example #2
0
    def get_entitled_hackathons_list(self, user):
        """Get hackathon id list that specific user is entitled to manage

        :type user_id: int
        :param user_id: id of user

        :rtype: list
        :return list of hackathon simple
        """
        user_filter = Q()
        if not user.is_super:
            user_filter = Q(user=user, role=HACK_USER_TYPE.ADMIN)

        hids = [uh.hackathon.id for uh in UserHackathon.objects(user_filter).no_dereference().only("hackathon")]
        hack_list = Hackathon.objects(id__in=hids).only(
            'name',
            'display_name',
            'ribbon',
            'short_description',
            'location',
            'banners',
            'status',
            'creator',
            'type',
            'config',
            'event_start_time',
            'event_end_time').order_by("-event_end_time")

        all_hackathon = [h.dic() for h in hack_list]
        return all_hackathon
    def check_hackathon_for_pre_allocate_expr(self):
        """Check all hackathon for pre-allocate

        Add an interval job for hackathon if it's pre-allocate is enabled.
        Otherwise try to remove the schedule job
        """
        hackathon_list = Hackathon.objects()
        for hack in hackathon_list:
            job_id = "pre_allocate_expr_" + str(hack.id)
            is_job_exists = self.scheduler.has_job(job_id)
            if self.__is_pre_allocate_enabled(hack):
                if is_job_exists:
                    self.log.debug("pre_allocate job already exists for hackathon %s" % str(hack.name))
                    continue

                self.log.debug("add pre_allocate job for hackathon %s" % str(hack.name))
                next_run_time = self.util.get_now() + timedelta(seconds=(20 * random.random()))
                pre_allocate_interval = self.__get_pre_allocate_interval(hack)
                self.scheduler.add_interval(feature="expr_manager",
                                            method="pre_allocate_expr",
                                            id=job_id,
                                            context=Context(hackathon_id=hack.id),
                                            next_run_time=next_run_time,
                                            seconds=pre_allocate_interval
                                            )
            elif is_job_exists:
                self.log.debug("remove job for hackathon %s since pre_allocate is disabled" % str(hack.id))
                self.scheduler.remove_job(job_id)
        return True
Example #4
0
    def pre_allocate_expr(self, context):
        # TODO: too complex, not check
        hackathon_id = context.hackathon_id
        self.log.debug("executing pre_allocate_expr for hackathon %s " % hackathon_id)
        hackathon = Hackathon.objects(id=hackathon_id).first()
        hackathon_templates = hackathon.templates
        for template in hackathon_templates:
            try:
                template = template
                pre_num = int(hackathon.config.get(HACKATHON_CONFIG.PRE_ALLOCATE_NUMBER, 1))
                query = Q(status=EStatus.STARTING) | Q(status=EStatus.RUNNING)
                curr_num = Experiment.objects(user=None, hackathon=hackathon, template=template).filter(query).count()
                self.log.debug("pre_alloc_exprs: pre_num is %d, curr_num is %d, remain_num is %d " %
                               (pre_num, curr_num, pre_num - curr_num))

                # TODO Should support VE_PROVIDER.K8S only in future after k8s Template is supported
                # if template.provider == VE_PROVIDER.K8S:
                if curr_num < pre_num:
                    start_num = Experiment.objects(user=None, template=template, status=EStatus.STARTING).count()
                    allowed_currency = int(hackathon.config.get(HACKATHON_CONFIG.PRE_ALLOCATE_CONCURRENT, 1))
                    if start_num >= allowed_currency:
                        self.log.debug(
                            "there are already %d Experiments starting, will check later ... " % allowed_currency)
                        return
                    else:
                        remain_num = min(allowed_currency, pre_num) - start_num
                        self.log.debug(
                            "no starting template: %s , remain num is %d ... " % (template.name, remain_num))
                        self.start_pre_alloc_exprs(None, template.name, hackathon.name, remain_num)
                        break
            except Exception as e:
                self.log.error(e)
                self.log.error("check default experiment failed")
    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_hackathon_for_pre_allocate_expr(self):
        """Check all hackathon for pre-allocate

        Add an interval job for hackathon if it's pre-allocate is enabled.
        Otherwise try to remove the schedule job
        """
        hackathon_list = Hackathon.objects()
        for hack in hackathon_list:
            job_id = "pre_allocate_expr_" + str(hack.id)
            is_job_exists = self.scheduler.has_job(job_id)
            if self.__is_pre_allocate_enabled(hack):
                if is_job_exists:
                    self.log.debug(
                        "pre_allocate job already exists for hackathon %s" %
                        str(hack.name))
                    continue

                self.log.debug("add pre_allocate job for hackathon %s" %
                               str(hack.name))
                next_run_time = self.util.get_now() + timedelta(
                    seconds=(20 * random.random()))
                pre_allocate_interval = self.__get_pre_allocate_interval(hack)
                self.scheduler.add_interval(
                    feature="expr_manager",
                    method="pre_allocate_expr",
                    id=job_id,
                    context=Context(hackathon_id=hack.id),
                    next_run_time=next_run_time,
                    seconds=pre_allocate_interval)
            elif is_job_exists:
                self.log.debug(
                    "remove job for hackathon %s since pre_allocate is disabled"
                    % str(hack.id))
                self.scheduler.remove_job(job_id)
        return True
    def create_new_hackathon(self, context):
        """Create new hackathon based on the http body

        Hackathon name is unique so duplicated names are not allowd.

        :type context: Context
        :param context: the body of http request that contains fields to create a new hackathon

        :rtype: dict
        """
        if Hackathon.objects(name=context.name).count() > 0:
            raise PreconditionFailed("hackathon name already exists")

        self.log.debug("add a new hackathon:" + context.name)
        new_hack = self.__create_hackathon(g.user, context)

        self.create_hackathon_notice(
            new_hack.id, HACK_NOTICE_EVENT.HACK_CREATE,
            HACK_NOTICE_CATEGORY.HACKATHON)  # hackathon create

        # init data is for local only
        if self.util.is_local():
            self.__create_default_data_for_local(new_hack)

        return new_hack.dic()
 def get_recyclable_hackathon_list(self):
     # todo filter hackathons by hackathon.config in a db-level if possible
     hackathons = Hackathon.objects(
         status=HACK_STATUS.ONLINE,
         event_start_time__lt=self.util.get_now(),
         event_end_time__gt=self.util.get_now()).all()
     return [h for h in hackathons if self.is_recycle_enabled(h)]
 def get_recyclable_hackathon_list(self):
     # todo filter hackathons by hackathon.config in a db-level if possible
     hackathons = Hackathon.objects(status=HACK_STATUS.ONLINE,
                                    event_start_time__lt=self.util.get_now(),
                                    event_end_time__gt=self.util.get_now()
                                    ).all()
     return filter(lambda h: self.is_recycle_enabled(h), hackathons)
Example #10
0
    def get_hackathon_by_id(self, hackathon_id):
        """Query hackathon by id
        :type hackathon_id: str or ObjectId are both ok
        :param hackathon_id: _id of hackathon

        :return hackathon instance or None
        """
        return Hackathon.objects(id=hackathon_id).first()
    def get_hackathon_by_id(self, hackathon_id):
        """Query hackathon by id
        :type hackathon_id: str or ObjectId are both ok
        :param hackathon_id: _id of hackathon

        :return hackathon instance or None
        """
        return Hackathon.objects(id=hackathon_id).first()
Example #12
0
    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_certificates_by_expr(self, expr_id):
        """Get certificates by experiment id
        """
        # expr = self.db.get_object(Experiment, expr_id)
        expr = Experiment.objects(id=expr_id)
        # hak = self.db.find_all_objects_by(HackathonAzureKey, hackathon_id=expr.hackathon_id)
        hak = Hackathon.objects(id=expr.hackathon_id).first().azure_keys[0]
        if not hak:
            raise Exception("no azure key configured")

        return map(lambda key: self.db.get_object(AzureKey, key.azure_key_id), hak)
    def get_certificates_by_expr(self, expr_id):
        """Get certificates by experiment id
        """
        # expr = self.db.get_object(Experiment, expr_id)
        expr = Experiment.objects(id=expr_id)
        # hak = self.db.find_all_objects_by(HackathonAzureKey, hackathon_id=expr.hackathon_id)
        hak = Hackathon.objects(id=expr.hackathon_id).first().azure_keys[0]
        if not hak:
            raise Exception("no azure key configured")

        return map(lambda key: self.db.get_object(AzureKey, key.azure_key_id), hak)
 def schedule_pre_allocate_host_server_job(self):
     """
     Schedule pre-allocate host server for every hackathon found in DB table:hackathon
     """
     self.log.debug('Begin to check host server and prepare resource.')
     min_avavilabe_container = 5
     for hackathon in Hackathon.objects():
         if self.__exist_request_host_server_by_hackathon_id(min_avavilabe_container, hackathon.id):
             continue
         if not self.start_new_docker_host_vm(hackathon):
             self.log.error('Schedule pre-allocate host server for hackathon:%s failed.' % hackathon.name)
Example #16
0
    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_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_hackathon_by_name(self, name):
        """Get hackathon accoring the unique name

        :type name: str|unicode
        :param name: name of hackathon

        :rtype: Hackathon
        :return hackathon instance if found else None
        """
        if not name:
            return None

        return Hackathon.objects(name=name).first()
Example #19
0
    def get_hackathon_by_name(self, name):
        """Get hackathon accoring the unique name

        :type name: str|unicode
        :param name: name of hackathon

        :rtype: Hackathon
        :return hackathon instance if found else None
        """
        if not name:
            return None

        return Hackathon.objects(name=name).first()
Example #20
0
 def schedule_pre_allocate_host_server_job(self):
     """
     Schedule pre-allocate host server for every hackathon found in DB table:hackathon
     """
     self.log.debug('Begin to check host server and prepare resource.')
     min_avavilabe_container = 5
     for hackathon in Hackathon.objects():
         if self.__exist_request_host_server_by_hackathon_id(
                 min_avavilabe_container, hackathon.id):
             continue
         if not self.start_new_docker_host_vm(hackathon):
             self.log.error(
                 'Schedule pre-allocate host server for hackathon:%s failed.'
                 % hackathon.name)
    def get_entitled_hackathons_list(self, user):
        """Get hackathon id list that specific user is entitled to manage

        :rtype: list
        :return list of hackathon simple
        """

        if not user.is_super:
            hack_list = UserHackathon.objects(user=user, role=HACK_USER_TYPE.ADMIN).distinct("hackathon")
            hack_list.sort(key=lambda s: s.create_time, reverse=True)
        else:
            hack_list = Hackathon.objects().all().order_by("-create_time")

        all_hackathon = [h.dic() for h in hack_list]
        return all_hackathon
Example #22
0
    def get_entitled_hackathons_list(self, user):
        """Get hackathon id list that specific user is entitled to manage

        :rtype: list
        :return list of hackathon simple
        """

        if not user.is_super:
            hack_list = UserHackathon.objects(
                user=user, role=HACK_USER_TYPE.ADMIN).distinct("hackathon")
            hack_list.sort(key=lambda s: s.create_time, reverse=True)
        else:
            hack_list = Hackathon.objects().all().order_by("-create_time")

        all_hackathon = [h.dic() for h in hack_list]
        return all_hackathon
    def __load_azure_key_id(self, context):
        # todo which key to use? how to support multi subscription?
        azure_key = None
        if "azure_key_id" in context:
            azure_key = AzureKey.objects(id=context.azure_key_id).first()

        if not azure_key:
            expr = Experiment.objects(id=context.experiment_id).only("azure_key").first()
            azure_key = expr.azure_key

        if not azure_key:
            hackathon = Hackathon.objects(id=context.hackathon_id).first()
            if not hackathon or (len(hackathon.azure_keys) == 0):
                raise Exception("no azure key configured")
            azure_key = hackathon.azure_keys[0]
            context.azure_key_id = azure_key.id

        return azure_key
    def __load_azure_key_id(self, context):
        # todo which key to use? how to support multi subscription?
        azure_key = None
        if "azure_key_id" in context:
            azure_key = AzureKey.objects(id=context.azure_key_id).first()

        if not azure_key:
            expr = Experiment.objects(id=context.experiment_id).only("azure_key").first()
            azure_key = expr.azure_key

        if not azure_key:
            hackathon = Hackathon.objects(id=context.hackathon_id).first()
            if not hackathon or (len(hackathon.azure_keys) == 0):
                raise Exception("no azure key configured")
            azure_key = hackathon.azure_keys[0]
            context.azure_key_id = azure_key.id

        return azure_key
 def validate_hackathon_name(self):
     if HTTP_HEADER.HACKATHON_NAME in request.headers:
         try:
             hackathon_name = request.headers[HTTP_HEADER.HACKATHON_NAME]
             hackathon = Hackathon.objects(name=hackathon_name).first()
             if hackathon:
                 g.hackathon = hackathon
                 return True
             else:
                 self.log.debug("cannot find hackathon by name %s" % hackathon_name)
                 return False
         except Exception as ex:
             self.log.error(ex)
             self.log.debug("hackathon_name invalid")
             return False
     else:
         self.log.debug("hackathon_name not found in headers")
         return False
Example #26
0
    def pre_allocate_expr(self, context):
        # TODO: too complex, not check
        hackathon_id = context.hackathon_id
        self.log.debug("executing pre_allocate_expr for hackathon %s " % hackathon_id)
        hackathon = Hackathon.objects(id=hackathon_id).first()
        hackathon_templates = hackathon.templates
        for template in hackathon_templates:
            try:
                template = template
                pre_num = int(hackathon.config.get("pre_allocate_number", 1))
                query = Q(status=EStatus.STARTING) | Q(status=EStatus.RUNNING)
                curr_num = Experiment.objects(user=None, hackathon=hackathon, template=template).filter(query).count()
                if template.provider == VE_PROVIDER.AZURE:
                    if curr_num < pre_num:
                        remain_num = pre_num - curr_num
                        start_num = Experiment.objects(user=None, template=template, status=EStatus.STARTING).count()
                        if start_num > 0:
                            self.log.debug("there is an azure env starting, will check later ... ")
                            return
                        else:
                            self.log.debug(
                                "no starting template: %s , remain num is %d ... " % (template.name, remain_num))
                            self.start_expr(None, template.name, hackathon.name)
                            break
                elif template.provider == VE_PROVIDER.DOCKER:
                    if hackathon.config.get('cloud_provider') == CLOUD_PROVIDER.ALAUDA:
                        # don't create pre-env if alauda used
                        continue

                    self.log.debug(
                        "template name is %s, hackathon name is %s" % (template.name, hackathon.name))
                    if curr_num < pre_num:
                        remain_num = pre_num - curr_num
                        start_num = Experiment.objects(user=None, template=template, status=EStatus.STARTING).count()
                        if start_num > 0:
                            self.log.debug("there is an docker container starting, will check later ... ")
                            return
                        self.log.debug("no idle template: %s, remain num is %d ... " % (template.name, remain_num))
                        self.start_expr(None, template.name, hackathon.name)
                        break
            except Exception as e:
                self.log.error(e)
                self.log.error("check default experiment failed")
    def get_docker_host_server(self, context):
        hackathon = Hackathon.objects(id=context.hackathon_id).no_dereference().first()
        try:
            host_resp = self.docker_host_manager.get_available_docker_host(hackathon)
        except Exception as e:
            self.log.error(e)
            host_resp = Context(state=DHS_QUERY_STATE.ONGOING)

        context.trial = context.get("trial", 0) + 1
        if host_resp.state == DHS_QUERY_STATE.SUCCESS:
            # assign ports
            self.__assign_ports(context, host_resp.docker_host_server)
        elif host_resp.state == DHS_QUERY_STATE.ONGOING and context.trial < 20:
            # tried up to 20 times
            self.log.debug("host servers are all busy, %d times tried, will retry in 3 seconds" % context.trial)
            self.scheduler.add_once(FEATURE, "get_docker_host_server", context, seconds=3)
        else:
            self.log.error("no available host server")
            self._on_virtual_environment_failed(context)
    def get_docker_host_server(self, context):
        hackathon = Hackathon.objects(id=context.hackathon_id).no_dereference().first()
        try:
            host_resp = self.docker_host_manager.get_available_docker_host(hackathon)
        except Exception as e:
            self.log.error(e)
            host_resp = Context(state=DHS_QUERY_STATE.ONGOING)

        context.trial = context.get("trial", 0) + 1
        if host_resp.state == DHS_QUERY_STATE.SUCCESS:
            # assign ports
            self.__assign_ports(context, host_resp.docker_host_server)
        elif host_resp.state == DHS_QUERY_STATE.ONGOING and context.trial < 20:
            # tried up to 20 times
            self.log.debug("host servers are all busy, %d times tried, will retry in 3 seconds" % context.trial)
            self.scheduler.add_once(FEATURE, "get_docker_host_server", context, seconds=3)
        else:
            self.log.debug("no available host server")
            self._on_virtual_environment_failed(context)
Example #29
0
 def validate_hackathon_name(self):
     if HTTP_HEADER.HACKATHON_NAME in request.headers:
         try:
             hackathon_name = request.headers[HTTP_HEADER.HACKATHON_NAME]
             hackathon = Hackathon.objects(name=hackathon_name).first()
             if hackathon:
                 g.hackathon = hackathon
                 return True
             else:
                 self.log.debug("cannot find hackathon by name %s" %
                                hackathon_name)
                 return False
         except Exception as ex:
             self.log.error(ex)
             self.log.debug("hackathon_name invalid")
             return False
     else:
         self.log.debug("hackathon_name not found in headers")
         return False
    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()
        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.
            # TODO
            pass
        else:
            order_by_condition = '-id'

        # perform db query with pagination
        pagination = Hackathon.objects(status_filter & name_filter).order_by(order_by_condition).paginate(page,
                                                                                                          per_page)

        user = None
        if self.user_manager.validate_login():
            user = g.user

        def func(hackathon):
            return self.__get_hackathon_detail(hackathon, user)

        # return serializable items as well as total count
        return self.util.paginate(pagination, func)
    def __get_sms_object(self, hackathon_id):
        """
        Get ServiceManagementService object by Azure account which is related to hackathon_id

        :param hackathon_id: the id of hackathon
        :type hackathon_id: integer

        :return: ServiceManagementService object
        :rtype: class 'azure.servicemanagement.servicemanagementservice.ServiceManagementService'
        """
        hackathon_azure_keys = Hackathon.objects(id=hackathon_id).first().azure_keys

        if len(hackathon_azure_keys) == 0:
            self.log.error('Found no azure key with Hackathon:%d' % hackathon_id)
            return None

        hackathon_azure_key = hackathon_azure_keys[0]
        sms = ServiceManagementService(hackathon_azure_key.subscription_id,
                                       hackathon_azure_key.get_local_pem_url(),
                                       host=hackathon_azure_key.management_host)
        return sms
    def create_new_hackathon(self, context):
        """Create new hackathon based on the http body

        Hackathon name is unique so duplicated names are not allowd.

        :type context: Context
        :param context: the body of http request that contains fields to create a new hackathon

        :rtype: dict
        """
        if Hackathon.objects(name=context.name).count() > 0:
            raise PreconditionFailed("hackathon name already exists")

        self.log.debug("add a new hackathon:" + context.name)
        new_hack = self.__create_hackathon(g.user, context)

        # init data is for local only
        if self.util.is_local():
            self.__create_default_data_for_local(new_hack)

        self.create_hackathon_notice(new_hack.id, HACK_NOTICE_EVENT.HACK_CREATE, HACK_NOTICE_CATEGORY.HACKATHON)

        return new_hack.dic()
    def __get_sms_object(self, hackathon_id):
        """
        Get ServiceManagementService object by Azure account which is related to hackathon_id

        :param hackathon_id: the id of hackathon
        :type hackathon_id: integer

        :return: ServiceManagementService object
        :rtype: class 'azure.servicemanagement.servicemanagementservice.ServiceManagementService'
        """
        hackathon_azure_keys = Hackathon.objects(
            id=hackathon_id).first().azure_keys

        if len(hackathon_azure_keys) == 0:
            self.log.error('Found no azure key with Hackathon:%d' %
                           hackathon_id)
            return None

        hackathon_azure_key = hackathon_azure_keys[0]
        sms = ServiceManagementService(
            hackathon_azure_key.subscription_id,
            hackathon_azure_key.get_local_pem_url(),
            host=hackathon_azure_key.management_host)
        return sms
    def get_hackathon_notice_list(self, body):
        """
        list hackathon notices, notices are paginated, can be filtered by hackathon_name, event and category,
        can be ordered by update_time, event and category.

        :type body: Context
        :param body: valid key/values(all key/values are optional)
            body = {
                hackathon_name: string,                  // filter by hackathon_name, default unfiltered
                filter_by_user: '******' | 'all',         // filter by user, default filter all notice that has specfic receivers
                category: 'int[,int...]',                // filter by category, default unfiltered
                event: 'int[,int...]',                   // filter by event, default unfiltered
                order_by: 'time' | 'event' | 'category', // order by update_time, event, category, default by time
                page: int,                               // page number after pagination, start from 1, default 1
                per_page: int                            // items per page, default 1000
            }

        :return: json style text, see util.Utility

        ::Example:
        : body = { order_by: 'time', category: '1,2,3', page: 1, per_page: 6 }
            search first 6 notices ordered by time, filtered by: category in [1,2,3]
        : body = { hackathon_name: 'hackathon', event: '1', order_by: 'event' }
            search first 1000 notices ordered by event, filtered by event == 1 and hackathon_name == 'hackathon'
        """

        hackathon_name = body.get("hackathon_name")
        filter_by_user = body.get("filter_by_user", "")
        notice_category = body.get("category")
        notice_event = body.get("event")
        order_by = body.get("order_by", "time")
        page = int(body.get("page", 1))
        per_page = int(body.get("per_page", 1000))

        hackathon_filter = Q()
        category_filter = Q()
        event_filter = Q()
        user_filter = Q(receiver=None)
        is_read_filter = Q()
        order_by_condition = '-update_time'

        if hackathon_name: #list notices that belong to specfic hackathon
            hackathon = Hackathon.objects(name=hackathon_name).only('name').first()
            if hackathon:
                hackathon_filter = Q(hackathon=hackathon)
            else:
                return not_found('hackathon_name not found')
        else: #only list online hackathons' notices or notices that not belong to any hackathon
            online_hackathon = Hackathon.objects(status=HACK_STATUS.ONLINE)
            hackathon_filter = Q(hackathon__in=online_hackathon) | Q(hackathon=None)

        if filter_by_user:  # only return notices that are sent to the login user
            user = None
            if self.user_manager.validate_login():
                user = g.user
                user_filter = Q(receiver=user)
                if filter_by_user == 'unread':
                    is_read_filter = Q(is_read=False)
            else:
                return bad_request("please login first")

        if notice_category:
            notice_category_tuple = tuple([int(category) for category in notice_category.split(',')])
            category_filter = Q(category__in=notice_category_tuple)
        if notice_event:
            notice_event_tuple = tuple([int(event) for event in notice_event.split(',')])
            event_filter = Q(event__in=notice_event_tuple)

        if order_by == 'category':
            order_by_condition = '+category'
        elif order_by == 'event':
            order_by_condition = '+event'
        else:
            order_by_condition = '-update_time'

        pagination = HackathonNotice.objects(
            hackathon_filter & category_filter & event_filter & user_filter & is_read_filter
        ).order_by(
            order_by_condition
        ).paginate(page, per_page)

        def func(hackathon_notice):
            return hackathon_notice.dic()

        # return serializable items as well as total count
        return self.util.paginate(pagination, func)
    def get_hackathon_notice_list(self, body):
        """
        list hackathon notices, notices are paginated, can be filtered by hackathon_name, event and category,
        can be ordered by update_time, event and category.

        :type body: Context
        :param body: valid key/values(all key/values are optional)
            body = {
                hackathon_name: string,                  // filter by hackathon_name, default unfiltered
                category: 'int[,int...]',                // filter by category, default unfiltered
                event: 'int[,int...]',                   // filter by event, default unfiltered
                order_by: 'time' | 'event' | 'category', // order by update_time, event, category, default by time
                page: int,                               // page number after pagination, start from 1, default 1
                per_page: int                            // items per page, default 1000
            }

        :return: json style text, see util.Utility

        ::Example:
        : body = { order_by: 'time', category: '1,2,3', page: 1, per_page: 6 }
            search first 6 notices ordered by time, filtered by: category in [1,2,3]
        : body = { hackathon_name: 'hackathon', event: '1', order_by: 'event' }
            search first 1000 notices ordered by event, filtered by event == 1 and hackathon_name == 'hackathon'
        """

        hackathon_name = body.get("hackathon_name")
        notice_category = body.get("category")
        notice_event = body.get("event")
        order_by = body.get("order_by", "time")
        page = int(body.get("page", 1))
        per_page = int(body.get("per_page", 1000))

        hackathon_filter = Q()
        category_filter = Q()
        event_filter = Q()
        order_by_condition = '-update_time'

        if hackathon_name:
            hackathon = Hackathon.objects(name=hackathon_name).only('name').first()
            if hackathon:
                hackathon_filter = Q(hackathon=hackathon)
            else:
                return not_found('hackathon_name not found')

        if notice_category:
            notice_category_tuple = tuple([int(category) for category in notice_category.split(',')])
            category_filter = Q(category__in=notice_category_tuple)
        if notice_event:
            notice_event_tuple = tuple([int(event) for event in notice_event.split(',')])
            event_filter = Q(event__in=notice_event_tuple)

        if order_by == 'category':
            order_by_condition = '+category'
        elif order_by == 'event':
            order_by_condition = '+event'
        else:
            order_by_condition = '-update_time'

        pagination = HackathonNotice.objects(
            hackathon_filter & category_filter & event_filter
        ).order_by(
            order_by_condition
        ).paginate(page, per_page)

        def func(hackathon_notice):
            return hackathon_notice.dic()

        # return serializable items as well as total count
        return self.util.paginate(pagination, func)
 def get_online_hackathons(self):
     return Hackathon.objects(status=HACK_STATUS.ONLINE)
 def get_recyclable_hackathon_list(self):
     # todo filter hackathons in a db-level
     hackathons = Hackathon.objects().all()
     return filter(lambda h: self.is_recycle_enabled(h), hackathons)
Example #38
0
    def get_hackathon_notice_list(self, body):
        """
        list hackathon notices, notices are paginated, can be filtered by hackathon_name, event and category,
        can be ordered by update_time, event and category.

        :type body: Context
        :param body: valid key/values(all key/values are optional)
            body = {
                hackathon_name: string,                  // filter by hackathon_name, default unfiltered
                filter_by_user: '******' | 'all',         // filter by user, default filter all notice that has specfic receivers
                category: 'int[,int...]',                // filter by category, default unfiltered
                event: 'int[,int...]',                   // filter by event, default unfiltered
                order_by: 'time' | 'event' | 'category', // order by update_time, event, category, default by time
                page: int,                               // page number after pagination, start from 1, default 1
                per_page: int                            // items per page, default 1000
            }

        :return: json style text, see util.Utility

        ::Example:
        : body = { order_by: 'time', category: '1,2,3', page: 1, per_page: 6 }
            search first 6 notices ordered by time, filtered by: category in [1,2,3]
        : body = { hackathon_name: 'hackathon', event: '1', order_by: 'event' }
            search first 1000 notices ordered by event, filtered by event == 1 and hackathon_name == 'hackathon'
        """

        hackathon_name = body.get("hackathon_name")
        filter_by_user = body.get("filter_by_user", "")
        notice_category = body.get("category")
        notice_event = body.get("event")
        order_by = body.get("order_by", "time")
        page = int(body.get("page", 1))
        per_page = int(body.get("per_page", 1000))

        hackathon_filter = Q()
        category_filter = Q()
        event_filter = Q()
        user_filter = Q(receiver=None)
        is_read_filter = Q()
        order_by_condition = '-update_time'

        if hackathon_name:  #list notices that belong to specfic hackathon
            hackathon = Hackathon.objects(
                name=hackathon_name).only('name').first()
            if hackathon:
                hackathon_filter = Q(hackathon=hackathon)
            else:
                return not_found('hackathon_name not found')
        else:  #only list online hackathons' notices or notices that not belong to any hackathon
            online_hackathon = Hackathon.objects(status=HACK_STATUS.ONLINE)
            hackathon_filter = Q(hackathon__in=online_hackathon) | Q(
                hackathon=None)

        if filter_by_user:  # only return notices that are sent to the login user
            user = None
            if self.user_manager.validate_login():
                user = g.user
                user_filter = Q(receiver=user)
                if filter_by_user == 'unread':
                    is_read_filter = Q(is_read=False)
            else:
                return bad_request("please login first")

        if notice_category:
            notice_category_tuple = tuple(
                [int(category) for category in notice_category.split(',')])
            category_filter = Q(category__in=notice_category_tuple)
        if notice_event:
            notice_event_tuple = tuple(
                [int(event) for event in notice_event.split(',')])
            event_filter = Q(event__in=notice_event_tuple)

        if order_by == 'category':
            order_by_condition = '+category'
        elif order_by == 'event':
            order_by_condition = '+event'
        else:
            order_by_condition = '-update_time'

        pagination = HackathonNotice.objects(
            hackathon_filter & category_filter & event_filter & user_filter
            & is_read_filter).order_by(order_by_condition).paginate(
                page, per_page)

        def func(hackathon_notice):
            return hackathon_notice.dic()

        # return serializable items as well as total count
        return self.util.paginate(pagination, func)
Example #39
0
    def pre_allocate_expr(self, context):
        # TODO: too complex, not check
        hackathon_id = context.hackathon_id
        self.log.debug("executing pre_allocate_expr for hackathon %s " %
                       hackathon_id)
        hackathon = Hackathon.objects(id=hackathon_id).first()
        hackathon_templates = hackathon.templates
        for template in hackathon_templates:
            try:
                template = template
                pre_num = int(hackathon.config.get("pre_allocate_number", 1))
                query = Q(status=EStatus.STARTING) | Q(status=EStatus.RUNNING)
                curr_num = Experiment.objects(
                    user=None, hackathon=hackathon,
                    template=template).filter(query).count()
                if template.provider == VE_PROVIDER.AZURE:
                    if curr_num < pre_num:
                        remain_num = pre_num - curr_num
                        start_num = Experiment.objects(
                            user=None,
                            template=template,
                            status=EStatus.STARTING).count()
                        if start_num > 0:
                            self.log.debug(
                                "there is an azure env starting, will check later ... "
                            )
                            return
                        else:
                            self.log.debug(
                                "no starting template: %s , remain num is %d ... "
                                % (template.name, remain_num))
                            self.start_expr(None, template.name,
                                            hackathon.name)
                            break
                elif template.provider == VE_PROVIDER.DOCKER:
                    if hackathon.config.get(
                            'cloud_provider') == CLOUD_PROVIDER.ALAUDA:
                        # don't create pre-env if alauda used
                        continue

                    self.log.debug(
                        "template name is %s, hackathon name is %s" %
                        (template.name, hackathon.name))
                    if curr_num < pre_num:
                        remain_num = pre_num - curr_num
                        start_num = Experiment.objects(
                            user=None,
                            template=template,
                            status=EStatus.STARTING).count()
                        if start_num > 0:
                            self.log.debug(
                                "there is an docker container starting, will check later ... "
                            )
                            return
                        self.log.debug(
                            "no idle template: %s, remain num is %d ... " %
                            (template.name, remain_num))
                        self.start_expr(None, template.name, hackathon.name)
                        break
            except Exception as e:
                self.log.error(e)
                self.log.error("check default experiment failed")
Example #40
0
 def get_online_hackathons(self):
     return Hackathon.objects(status=HACK_STATUS.ONLINE)