view src/server/session_iface.py @ 960:e59edcae4c18

pages(session): added method to handle reload resistant page specific data: Liberiva Page can now register session data specific to a page using ISatSession methods (see docstrings for details). Those data can resist a page reload, are specific to a session and a page.
author Goffi <goffi@goffi.org>
date Fri, 27 Oct 2017 18:31:42 +0200
parents 67bf14c91d5c
children fd4eae654182
line wrap: on
line source

#!/usr/bin/python
# -*- coding: utf-8 -*-

# Libervia: a SAT frontend
# Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org)

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
from zope.interface import Interface, Attribute, implements
from sat.tools.common import data_objects
import shortuuid

FLAGS_KEY = '_flags'

class ISATSession(Interface):
    profile = Attribute("Sat profile")
    jid = Attribute("JID associated with the profile")
    uuid = Attribute("uuid associated with the profile session")
    identities = Attribute("Identities of XMPP entities")


class SATSession(object):
    implements(ISATSession)

    def __init__(self, session):
        self.profile = None
        self.jid = None
        self.uuid = unicode(shortuuid.uuid())
        self.identities = data_objects.Identities()
        self.csrf_token = unicode(shortuuid.uuid())
        self.pages_data = {}  # used to keep data accross reloads (key is page instance)

    def getPageData(self, page, key):
        """get session data for a page

        @param page(LiberviaPage): instance of the page
        @param key(object): data key
        return (None, object): value of the key
            None if not found or page_data doesn't exist
        """
        return self.pages_data.get(page, {}).get(key)

    def popPageData(self, page, key, default=None):
        """like getPageData, but remove key once value is gotten

        @param page(LiberviaPage): instance of the page
        @param key(object): data key
        @param default(object): value to return if key is not found
        @return (object): found value or default
        """
        page_data = self.pages_data.get(page)
        if page_data is None:
            return default
        value = page_data.pop(key, default)
        if not page_data:
            # no need to keep unused page_data
            del self.pages_data[page]
        return value

    def setPageData(self, page, key, value):
        """set data to persist on reload

        @param page(LiberviaPage): instance of the page
        @param key(object): data key
        @param value(object): value to set
        @return (object): set value
        """
        page_data = self.pages_data.setdefault(page, {})
        page_data[key] = value
        return value

    def setPageFlag(self, page, flag):
        """set a flag for this page

        @param page(LiberviaPage): instance of the page
        @param flag(unicode): flag to set
        """
        flags = self.getPageData(page, FLAGS_KEY)
        if flags is None:
            flags = self.setPageData(page, FLAGS_KEY, set())
        flags.add(flag)

    def popPageFlag(self, page, flag):
        """return True if flag is set

        flag is removed if it was set
        @param page(LiberviaPage): instance of the page
        @param flag(unicode): flag to set
        @return (bool): True if flaag was set
        """
        page_data = self.pages_data.get(page, {})
        flags = page_data.get(FLAGS_KEY)
        if flags is None:
            return False
        if flag in flags:
            flags.remove(flag)
            # we remove data if they are not used anymore
            if not flags:
                del page_data[FLAGS_KEY]
            if not page_data:
                del self.pages_data[page]
            return True
        else:
            return False


class ISATGuestSession(Interface):
    id = Attribute("UUID of the guest")
    data = Attribute("data associated with the guest")


class SATGuestSession(object):
    implements(ISATGuestSession)

    def __init__(self, session):
        self.id = None
        self.data = None