コード例 #1
0
        def make_poll(response):
            session_id = _current_session_id()
            if session_id is None:
                return response

            _current_backend().poll(session_id)
            return response
コード例 #2
0
def logout():
    """
    Notify WebLab-Deusto that the user left the laboratory, so next user can enter.

    This process is not real time. What it happens is that WebLab-Deusto periodically is requesting
    whether the user is still alive or not. If you call logout, weblablib will reply the next time
    that the user left. So it may take some seconds for WebLab-Deusto to realize of that. You can
    regulate this time with ``WEBLAB_POLL_INTERVAL`` setting (defaults to 5).
    """
    session_id = _current_session_id()
    if session_id:
        _current_backend().force_exit(session_id)
コード例 #3
0
def store_initial_weblab_user_data():
    session_id = _current_session_id()
    if session_id:
        backend = _current_backend()
        current_user = backend.get_user(session_id)
        if current_user.active:
            g._initial_data = json.dumps(current_user.data)
コード例 #4
0
def get_weblab_user(cached=True):
    """
    Get the current user. If ``cached=True`` it will store it and return the same each time.
    If you need to get always a different one get it with ``cached=False``. In long tasks, for
    example, it's normal to call it with ``cached=False`` so it gets updated with whatever
    information comes from other threads.

    Two shortcuts exist to this function:
     * :data:`weblab_user`: it is equivalent to ``get_weblab_user(cached=True)``
     * :data:`socket_weblab_user`: it is equivalent to ``get_weblab_user(cached=False)``

    Given that the function always returns a :class:`CurrentUser` or :class:`ExpiredUser` or :class:`AnonymousUser`, it's safe to do things like::

       if not weblab_user.anonymous:
           print(weblab_user.username)
           print(weblab_user.username_unique)

    :param cached: if this method is called twice in the same thread, it will return the same object.
    """
    if cached and hasattr(g, 'weblab_user'):
        return g.weblab_user

    # Cached: then use Redis
    session_id = _current_session_id()
    if session_id is None:
        return _set_weblab_user_cache(AnonymousUser())

    user = _current_backend().get_user(session_id)
    # Store it for next requests in the same call
    return _set_weblab_user_cache(user)
コード例 #5
0
 def retrieve(self):
     backend = _current_backend()
     user = backend.get_user(self._user._session_id)
     if isinstance(user.data, DataHolder):
         self.update(user.data)
         for key in list(self):
             if key not in user.data:
                 self.pop(key, None)
コード例 #6
0
def dispose_user(session_id, waiting):
    backend = _current_backend()
    user = backend.get_user(session_id)
    if user.is_anonymous:
        raise NotFoundError()

    if isinstance(user, CurrentUser):
        current_expired_user = user.to_expired_user()
        deleted = backend.delete_user(session_id, current_expired_user)

        if deleted:
            try:
                weblab = _current_weblab()
                weblab._set_session_id(session_id)
                if weblab._on_dispose:

                    _set_weblab_user_cache(user)
                    try:
                        weblab._on_dispose()
                    except Exception:
                        traceback.print_exc()
                    update_weblab_user_data(response=None)
            finally:
                backend.finished_dispose(session_id)

            unfinished_tasks = backend.get_unfinished_tasks(session_id)
            for task_id in unfinished_tasks:
                unfinished_task = weblab.get_task(task_id)
                if unfinished_task:
                    unfinished_task.stop()

            while unfinished_tasks:
                unfinished_tasks = backend.get_unfinished_tasks(session_id)
                time.sleep(0.1)

            backend.clean_session_tasks(session_id)

            backend.report_session_deleted(session_id)

    if waiting:
        # if another thread has started the _dispose process, it might take long
        # to process it. But this (sessions) is the one that tells WebLab-Deusto
        # that someone else can enter in this laboratory. So we should wait
        # here until the process is over.

        while not backend.is_session_deleted(session_id):
            # In the future, instead of waiting, this could be returning that it is still finishing
            time.sleep(0.1)
コード例 #7
0
def update_weblab_user_data(response):
    # If a developer does:
    #
    # weblab_user.data["foo"] = "bar"
    #
    # Nothing is triggered in Redis. For this reason, after each request
    # we check that the data has changed or not.
    #
    session_id = _current_session_id()
    backend = _current_backend()
    if session_id:
        if weblab_user.active:
            # If there was no data in the beginning
            # OR there was data in the beginning and now it is different,
            # only then modify the current session
            if not hasattr(g,
                           '_initial_data') or g._initial_data != json.dumps(
                               weblab_user.data):
                backend.update_data(session_id, weblab_user.data)

    return response
コード例 #8
0
 def store(self):
     backend = _current_backend()
     data = self.copy()
     backend.update_data(self._user._session_id, data)
     self._initial_hash = self._get_hash(data)
コード例 #9
0
 def clean_actions(self, session_id): # pylint: disable=no-self-use
     """
     Remove all actions of a session_id
     """
     backend = _current_backend()
     backend.clean_actions(session_id)
コード例 #10
0
 def store_action(self, session_id, action_id, action): # pylint: disable=no-self-use
     """
     Adds a new raw action to a new or existing session_id
     """
     backend = _current_backend()
     backend.store_action(session_id, action_id, action)
コード例 #11
0
ファイル: views.py プロジェクト: labsland/weblablib
def _process_start_request(request_data):
    """ Auxiliar method, called also from the Flask CLI to fake_user """
    client_initial_data = request_data['client_initial_data']
    server_initial_data = request_data['server_initial_data']

    # Parse the initial date + assigned time to know the maximum time
    start_date_timestamp = server_initial_data.get(
        'priority.queue.slot.start.timestamp')
    if start_date_timestamp:  # if the time is available in timestamp, use it
        start_date = datetime.datetime.fromtimestamp(
            float(start_date_timestamp))
    else:
        # Otherwise, to keep backwards compatibility, assume that it's in the same timezone
        # as we are
        start_date_str = server_initial_data['priority.queue.slot.start']
        start_date_str, microseconds = start_date_str.split('.')
        difference = datetime.timedelta(microseconds=int(microseconds))
        start_date = datetime.datetime.strptime(
            start_date_str, "%Y-%m-%d %H:%M:%S") + difference

    slot_length = float(server_initial_data['priority.queue.slot.length'])
    max_date = start_date + datetime.timedelta(seconds=slot_length)
    locale = server_initial_data.get('request.locale')
    full_name = server_initial_data['request.full_name']

    experiment_name = server_initial_data[
        'request.experiment_id.experiment_name']
    category_name = server_initial_data['request.experiment_id.category_name']
    experiment_id = '{}@{}'.format(experiment_name, category_name)

    # Create a global session
    session_id = create_token()

    # Prepare adding this to backend
    user = CurrentUser(
        session_id=session_id,
        back=request_data['back'],
        last_poll=_current_timestamp(),
        max_date=float(_to_timestamp(max_date)),
        username=server_initial_data['request.username'],
        username_unique=server_initial_data['request.username.unique'],
        exited=False,
        data={},
        locale=locale,
        full_name=full_name,
        experiment_name=experiment_name,
        experiment_id=experiment_id,
        category_name=category_name,
        request_client_data=client_initial_data,
        request_server_data=server_initial_data,
        start_date=float(_to_timestamp(start_date)))

    backend = _current_backend()

    backend.add_user(
        session_id,
        user,
        expiration=30 +
        int(float(server_initial_data['priority.queue.slot.length'])))

    kwargs = {}
    scheme = current_app.config.get(ConfigurationKeys.WEBLAB_SCHEME)
    if scheme:
        kwargs['_scheme'] = scheme

    weblab = _current_weblab()
    if weblab._on_start:
        _set_weblab_user_cache(user)
        weblab._set_session_id(session_id)
        try:
            data = weblab._on_start(client_initial_data, server_initial_data)
        except Exception as error:
            traceback.print_exc()
            current_app.logger.warning(
                "Error calling _on_start: {}".format(error), exc_info=True)
            try:
                dispose_user(session_id, waiting=True)
            except Exception as nested_error:
                traceback.print_exc()
                current_app.logger.warning(
                    "Error calling _on_dispose after _on_start failed: {}".
                    format(nested_error),
                    exc_info=True)

            return dict(error=True, message="Error initializing laboratory")
        else:
            if data:
                user.data = data
            user.data.store_if_modified()
            update_weblab_user_data(response=None)

    link = url_for('weblab_callback_url',
                   session_id=session_id,
                   _external=True,
                   **kwargs)
    return dict(url=link, session_id=session_id)