Commits

Anonymous committed 962d107

PortletSession implementation

Comments (0)

Files changed (3)

portlets/models.py

+# -*- coding: utf-8 -*-
+
 # django imports
 from django import forms
 from django.contrib.contenttypes.models import ContentType
 from django.template.loader import render_to_string
 from django.utils.translation import ugettext_lazy as _
 
+from lxml import etree
+from random import choice
+from string import letters
+
+
+class ElementField(models.CharField):
+    """ Stores etree._Element into the database as CharField.
+        @author: lamikae
+    """
+
+    __metaclass__ = models.SubfieldBase
+
+    def get_db_prep_value(self, value):
+        return etree.tostring(value)
+
+    def to_python(self, value):
+        if isinstance(value, etree._Element):
+            return value
+        if value:
+            return etree.fromstring(value)
+
+
+def generate_session_name():
+    return ''.join(choice(letters) for i in xrange(6))
+
+def generate_session_element():
+    return '<portlet-session />'
+
+class PortletSession(models.Model):
+    """ Base portlet session. All portlet sessions should inherit from this class
+        and define attributes 'portlet' and 'user'.
+        @author: lamikae
+    """
+    # subclasses should define
+    # * user
+    # * portlet
+    # in a manner they like.
+    creation_time = models.DateField(auto_now_add=True)
+    name = models.CharField(unique=True, blank=False, max_length=6,
+        default=generate_session_name()
+        )
+    _Element = ElementField(max_length=512,
+        blank=False,
+        default=generate_session_element()
+        )
+
+    class Meta:
+        abstract = True
+
+    def __init__(self,*args,**kwargs):
+        """ Kwargs that are not model attributes are stored to the session etree.Element.
+            The session Element is accessed by get() and set() methods.
+        """
+        #print ' - - - portlets.PortletSession init'
+        #print args
+        #print kwargs
+        # extract session kwargs
+        session_kwargs = {}
+        for key in kwargs.keys():
+            # kwargs that are not for class attributes
+            if key not in self.__class__.__dict__.keys():
+                # are removed and stored from causing trouble at super __init__
+                session_kwargs[key] = kwargs.pop(key)
+
+        super(PortletSession, self).__init__(*args,**kwargs)
+
+        # insert kwargs to session
+        for (key,value) in session_kwargs.items():
+            try:
+                self._Element.set(key, value)
+            except:
+                import traceback
+                print traceback.format_exc()
+                print 'could not set session value '+ key
+
+        # update session with namespace
+        self.set('namespace', '__%s_%s__' % ('portlet',self.name))
+
+    def __unicode__(self):
+        return u'Portlet session %s: %s' % (self.id, self.name)
+
+    def get(self,k):
+        return self._Element.get(k)
+
+    def set(self,k,v):
+        return self._Element.set(k,v)
+
+
 class Portlet(models.Model):
     """Base portlet. All portlets should inherit from this class.
     """
     name = models.CharField(max_length=50)
 
     def __unicode__(self):
-        return self.name
+        return self.name
+
+
+### XXX: test mocks, need database tables
+
+from django.contrib.auth.models import User
+
+class MockPortlet(Portlet):
+    """ Used in tests.
+        @author: lamikae
+    """
+    def __unicode__(self):
+        return 'test_mock'
+
+class MockPortletSession(PortletSession):
+    """ Used in tests.
+        @author: lamikae
+    """
+    user = models.ForeignKey(User, null=True, unique=True)
+    portlet = models.ForeignKey(MockPortlet, null=True)

portlets/tests/__init__.py

 # -*- coding: utf-8 -*-
 from portlets_tests import *
+from portlet_session_tests import *

portlets/tests/portlet_session_tests.py

+# -*- coding: utf-8 -*-
+# @author: lamikae
+
+# django imports
+from django.contrib.flatpages.models import FlatPage
+from django.db import IntegrityError
+from django.template import RequestContext
+from django.test import TestCase
+from django.test.client import Client
+
+# django-portlets imports
+#from portlets.models import PortletAssignment
+#from portlets.models import PortletBlocking
+from portlets.models import PortletRegistration
+#from portlets.models import Slot
+#from portlets.models import Portlet
+#from portlets.models import PortletSession
+
+from portlets.models import MockPortlet, MockPortletSession
+
+import portlets.utils
+from lxml import etree
+
+
+class PortletSessionTestCase(TestCase):
+    """
+    """
+
+    def setUp(self):
+        self.portlet_parameter = u'value used for some random portlet parameter'
+
+    def test_portlet_session1(self):
+        """ Basic session behaviour
+        """
+        ### volatile session
+        session = MockPortletSession()
+        self.assert_(session)
+        del(session)
+
+        ### persistent session, no portlet
+        session = MockPortletSession.objects.create()
+        self.assert_(session)
+        self.assertEqual(
+            etree.tostring(session._Element),
+            '<portlet-session namespace="__portlet_%s__"/>' % session.name)
+        
+        session.set('some-parameter', 'some-value')
+        self.assertEqual(session.get('some-parameter'), 'some-value')
+
+        # save and reload object from database
+        id = session.id
+        name = session.name
+        session.save()
+        del(session)
+        session = MockPortletSession.objects.get(id=id)
+        self.assertEqual(session.name, name)
+        self.assertEqual(session.get('some-parameter'), 'some-value')
+
+    def test_portlet_session2(self):
+        """ Session init with extra kwargs
+        """
+        # persistent session
+        session = MockPortletSession.objects.create(
+            url = self.portlet_parameter, some_parameter='some-value')
+
+        self.assertEqual(session.get('url'), self.portlet_parameter)
+        self.assertEqual(session.get('some_parameter'), 'some-value')
+        self.assertEqual(session.get('namespace'), '__portlet_%s__' % session.name)
+        # set value and reload
+        session.set('year', '2010')
+        id = session.id
+        session.save()
+        del(session)
+        session = MockPortletSession.objects.get(id=id)
+        self.assertEqual(session.get('url'), self.portlet_parameter)
+        self.assertEqual(session.get('some_parameter'), 'some-value')
+        self.assertEqual(session.get('year'), '2010')
+
+    '''
+    def test_portlet_session3(self):
+        """ Persistent portlet session
+            XXX: decide how to do it
+        """
+        portlet = MockPortlet.objects.create(url=self.portlet_parameter)
+        self.assert_(portlet)
+        self.assert_(portlet.session)
+        self.assertEqual(portlet.session.get('url'), self.portlet_parameter)
+        self.assertEqual(portlet.session.get('namespace'), '__portlet_%s__' % portlet.session.name)
+    '''
+
+    '''
+    def test_session_callback(self):
+        """ PortletSession callback
+        """
+        def session_callback(session):
+            return {'some-parameter': 'some-value'}
+
+        session = MockPortletSession.objects.create(
+            session_callback=session_callback
+            )
+
+        self.assert_(session)
+        self.assertEqual(session.get('namespace'), '__portlet_%s__' % session.name)
+        self.assertEqual(session.get('some-parameter'), 'some-value')
+
+        portlet = TestMarionet.objects.create(
+            url = self.portlet_parameter,
+            session_callback=session_callback
+            )
+        self.assert_(portlet)
+        self.assert_(portlet.session)
+        self.assertEqual(portlet.session.get('url'), self.portlet_parameter)
+        self.assertEqual(portlet.session.get('namespace'), '__portlet_%s__' % portlet.session.name)
+        self.assertEqual(portlet.session.get('some-parameter'), 'some-value')
+    '''