Esempio n. 1
0
 def register_event_listener(cls):
     if cls.__initialized:
         return
     cls.__initialized = True
     comment_liked.connect(cls.on_liked)
     task_time_changed.connect(cls.on_task_time_changed)
     logger().debug(f'Event listener registered [class={cls.__name__}]')
Esempio n. 2
0
 def register_event_listener(cls):
     if cls.__initialized:
         return
     cls.__initialized = True
     # TODO: handle rejudge, which might convert a AC submission into WA
     submission_completed.connect(cls.on_submission_completed)
     task_time_changed.connect(cls.on_task_time_changed)
     logger().debug(f'Event listener registered [class={cls.__name__}]')
Esempio n. 3
0
 def add(
     cls,
     task: Task,
     required_number: int,
 ):
     req = cls.engine(
         task=task.id,
         required_number=required_number,
     ).save()
     requirement_added.send(req)
     logger().info(f'Requirement created [requirement={req.id}]')
     return cls(req)
Esempio n. 4
0
 def add(
     cls,
     task: Task,
     required_number: Optional[int] = None,
 ):
     params = {
         'task': task.id,
         'required_number': required_number,
     }
     params = {k: v for k, v in params.items() if v is not None}
     req = cls.engine(**params).save()
     requirement_added.send(req)
     logger().info(f'Requirement created [requirement={req.id}]')
     return cls(req)
Esempio n. 5
0
 def real_wrapper(*args, **ks):
     try:
         return inner_wrapper(*args, **ks)
     # if document not exists in db
     except DoesNotExist as e:
         return HTTPError(e, 404)
     # if args missing
     # TODO: this line may catch a unexpected exception
     #   which is hard to debug. Define a special exception
     #   may be a solution.
     except ValueError as e:
         return HTTPError(e, 500)
     except ValidationError as ve:
         logger().info(
             f'Validation error. [src={src}, err={ve.to_dict()}]')
         # TODO: provide more detailed information
         return HTTPError('Invalid parameter', 400)
Esempio n. 6
0
 def add(
     cls,
     task: Task,
     problems: List[Problem],
 ):
     if len(problems) == 0:
         raise ValueError('`problems` cannot be empty')
     if any(p not in task.course.problems for p in problems):
         raise ValueError('All problems must belong to the course')
     if any(not p.is_OJ for p in problems):
         raise ValueError('Only accept OJ problem')
     req = cls.engine(
         task=task.id,
         problems=[p.id for p in problems],
     ).save()
     requirement_added.send(req)
     logger().info(f'Requirement created [requirement={req.id}]')
     return cls(req)
Esempio n. 7
0
 def add(
     cls,
     task: Task,
     problem: Problem,
     required_number: Optional[int] = None,
     acceptance: Optional[int] = None,
 ):
     if problem.is_OJ:
         raise ValueError('Only accept normal problem')
     params = {
         'task': task.id,
         'problem': problem.id,
         'required_number': required_number,
         'acceptance': acceptance,
     }
     params = {k: v for k, v in params.items() if v is not None}
     req = cls.engine(**params).save()
     requirement_added.send(req)
     logger().info(f'Requirement created [requirement={req.id}]')
     return cls(req)
Esempio n. 8
0
 def add_submission(self, submission):
     logger().debug(
         f'New submission added to requirement [type=SolveOJProblem, id={self.id}]'
     )
     if not self.is_valid_submission(submission):
         return
     if submission.problem not in self.problems:
         return
     with get_redis_client().lock(f'{self}'):
         self.reload('records')
         user = submission.user
         if self.is_completed(user):
             return
         record = self.get_record(user)
         completes = record.completes
         problem = submission.problem
         if problem in completes:
             return
         completes.append(problem.id)
         logger().info(
             'User solved a new OJ problem '
             f'[user={user.id}, problem={problem.id}, requirement={self.id}]'
         )
         if len(completes) >= len(self.problems):
             record.completed_at = datetime.now()
             logger().info(
                 f'User complete requirement [user={user.id}, requirement={self.id}]'
             )
         self.set_record(user, record)
Esempio n. 9
0
def setup_app(
    config: str = 'mongo.config.Config',
    env: Optional[str] = None,
):
    '''
    setup flask app from config and pre-configured env
    '''
    # Reserve a "empty" school
    try:
        engine.School(abbr='', name='無').save()
    except NotUniqueError:
        pass
    # Create a flask app
    app = Flask(__name__)

    # Register error handler
    @app.errorhandler(SandboxNotFound)
    def on_sandbox_not_found(_):
        return HTTPError('There are no sandbox available', 503)

    app.url_map.strict_slashes = False
    app.json_encoder = PyShareJSONEncoder
    # Override flask's config by core config
    # Note: Although the config is overridden, `ENV` and `DEBUG` should
    #   still set by env var (according to official document)
    # Ref: https://flask.palletsprojects.com/en/2.0.x/config/#environment-and-debug-features
    for k in ('TESTING', 'ENV', 'DEBUG'):
        app.config[k] = config_lib.config[k]
    # Register flask blueprint
    api2name = [
        (auth_api, '/auth'),
        (problem_api, '/problem'),
        (test_api, '/test'),
        (user_api, '/user'),
        (comment_api, '/comment'),
        (submission_api, '/submission'),
        (tag_api, '/tag'),
        (course_api, '/course'),
        (attachment_api, '/attachment'),
        (notif_api, '/notif'),
        (sandbox_api, '/sandbox'),
        (school_api, '/school'),
        (task_api, '/task'),
        (requirement_api, '/requirement'),
    ]
    for api, name in api2name:
        app.register_blueprint(api, url_prefix=name)
    if config_lib.config.get('DEBUG') == True:
        logger().warning(
            'Load dummy resource API, don\'t'
            ' use this under production mode', )
        from model.dummy import dummy_api
        app.register_blueprint(dummy_api, url_prefix='/dummy')
    # Setup SocketIO server
    socketio = SocketIO(cors_allowed_origins='*')
    socketio.on_namespace(Notifier(Notifier.namespace))
    socketio.init_app(app)
    try:
        init = engine.AppConfig.objects(key='init').get()
    except DoesNotExist:
        init = engine.AppConfig(
            id='init',
            value=True,
        ).save()
    # Setup environment for testing
    if init.value == True:
        logger().info('First run. Start setup process')
        if env is not None:
            setup_env(env)
        sandbox.init()
        init.update(value=False)
    return app