Exemple #1
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)
Exemple #2
0
 def __call__(self, *args, **kwargs):
     """Runs the function in the same way, directly, without catching errors"""
     session_id = None  # only used if unique='user'
     if self._unique:
         if self._unique == 'global':
             locked = self._backend.lock_global_unique_task(self._name)
             if not locked:
                 raise AlreadyRunningError(
                     "This task ({}) has been sent in parallel and it is still running"
                     .format(self._name))
         elif self._unique == 'user':
             session_id = _current_session_id()
             locked = self._backend.lock_user_unique_task(
                 self._name, session_id)
             if not locked:
                 raise AlreadyRunningError(
                     "This task ({}) has been sent in parallel by {} and it is still running"
                     .format(self._name, session_id))
     try:
         return self._func(*args, **kwargs)
     finally:
         if self._unique:
             if self._unique == 'global':
                 self._backend.unlock_global_unique_task(self._name)
             elif self._unique == 'user':
                 self._backend.unlock_user_unique_task(
                     self._name, session_id)
Exemple #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)
Exemple #4
0
        def make_poll(response):
            session_id = _current_session_id()
            if session_id is None:
                return response

            _current_backend().poll(session_id)
            return response
Exemple #5
0
 def delay(self, *args, **kwargs):
     """
     Starts the function in a thread or in another process.
     It returns a WebLabTask object
     """
     session_id = _current_session_id()
     task_id = self._backend.new_task(session_id, self._name, args, kwargs)
     return WebLabTask(self._weblab, task_id)
Exemple #6
0
    def running_tasks(self):
        """
        Check which tasks are still running and return them.

        See also :meth:`WebLab.task` for examples.
        """
        session_id = _current_session_id()
        tasks = []
        for task_id in self._backend.get_unfinished_tasks(session_id):
            tasks.append(WebLabTask(self, task_id))
        return tasks
Exemple #7
0
    def tasks(self):
        """
        Return all the tasks created in the current session (completed or not)

        See also :meth:`WebLab.task` for examples.
        """
        session_id = _current_session_id()
        tasks = []
        for task_id in self._backend.get_all_tasks(session_id):
            tasks.append(WebLabTask(self, task_id))
        return tasks
Exemple #8
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)
Exemple #9
0
            def poll_after_request(response):
                """
                Poll after every request
                """
                if hasattr(g, 'poll_requested'):
                    poll_requested = g.poll_requested
                else:
                    poll_requested = False

                # Don't poll twice: if requested manually there is another after_this_request
                if not poll_requested:
                    session_id = _current_session_id()
                    if session_id:
                        self._backend.poll(session_id)

                return response
Exemple #10
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
Exemple #11
0
    def get_task(self, identifier):
        """
        Given a task of the current user, return the :class:`WebLabTask` object.

        The identifier can be:
          1. A ``task_id``
          2. A function name
          3. A function

        See also :meth:`WebLab.task` for examples.

        :param identifier: either a ``task_id``, a function name or a function.
        """
        name = identifier
        func = False
        if hasattr(identifier, '__code__'):
            name = identifier.__name__
            func = True

        if hasattr(identifier, '_func') and hasattr(identifier._func, '__code__'):
            name = identifier._func.__name__
            func = True

        if not func:
            task_data = self._backend.get_task(name)
            if task_data:
                # Don't return tasks of other users
                if task_data['session_id'] == _current_session_id():
                    return WebLabTask(self, task_data['task_id'])

        if has_app_context():
            # if no task_data or func is True:
            tasks = self.get_tasks(name)
            if tasks:
                return tasks[0]

        return None
Exemple #12
0
        def weblab_poll_script(logout_on_close=False, callback=None):
            """
            Create a HTML script that calls poll automatically.
            """
            if self.timeout <= 0:
                return Markup("<!-- timeout is 0 or negative; no script -->")

            weblab_timeout = int(1000 * self.timeout / 2)
            session_id = _current_session_id()
            if not session_id:
                return Markup("<!-- session_id not found; no script -->")

            if logout_on_close:
                logout_code = """
                $(window).bind("beforeunload", function() {
                    $.get("%(url)s");
                });
                """ % dict(url=url_for('weblab_logout_url', session_id=session_id))
            else:
                logout_code = ""

            if callback:
                callback_code = "{}();".format(callback)
            else:
                callback_code = ""

            return Markup("""<script>
                var WEBLAB_TIMEOUT = null;
                var WEBLAB_RETRIES = 3;
                if (window.jQuery !== undefined) {
                    var WEBLAB_INTERVAL_FUNCTION = function(){
                        $.get("%(url)s").done(function(result) {
                            if(!result.success) {
                                clearInterval(WEBLAB_TIMEOUT);
                                %(callback_code)s
                            } else {
                                WEBLAB_RETRIES = 3;
                            }
                        }).fail(function(errorData) {
                            if (WEBLAB_RETRIES > 0 && (errorData.status == 502 || errorData.status == 503)) {
                                WEBLAB_RETRIES -= 1;
                                setTimeout(WEBLAB_INTERVAL_FUNCTION, 1500); // Force a try-again in 1.5 seconds
                            } else {
                                clearInterval(WEBLAB_TIMEOUT);
                                %(callback_code)s
                            }
                        });
                    }
                    WEBLAB_TIMEOUT = setInterval(WEBLAB_INTERVAL_FUNCTION, %(timeout)s );
                    %(logout_code)s
                } else {
                    var msg = "weblablib error: jQuery not loaded BEFORE {{ weblab_poll_script() }}. Can't poll";
                    if (console && console.error) {
                        console.error(msg);
                    } else if (console && console.log) {
                        console.log(msg);
                    } else {
                        alert(msg);
                    }
                }
                </script>""" % dict(timeout=weblab_timeout, url=url_for('weblab_poll_url', session_id=session_id),
                                    logout_code=logout_code, callback_code=callback_code))