Stop invalidating the entire session before generating the page...
[zzz-spline-frontpage.git] / splinext / frontpage / controllers / frontpage.py
index 764b292..900c87b 100644 (file)
@@ -1,12 +1,14 @@
+import datetime
 import logging
 
 from pylons import config, request, response, session, tmpl_context as c, url
-from pylons.controllers.util import abort, redirect_to
+from pylons.controllers.util import abort, redirect
 from routes import request_config
 from sqlalchemy.orm.exc import NoResultFound
 
 from spline.lib import helpers as h
 from spline.lib.base import BaseController, render
+from spline.model import meta
 from splinext.frontpage.sources import max_age_to_datetime
 
 log = logging.getLogger(__name__)
@@ -52,7 +54,8 @@ class FrontPageController(BaseController):
         global_max_age = max_age_to_datetime(
             config['spline-frontpage.max_age'])
 
-        for source in config['spline-frontpage.sources']:
+        c.sources = config['spline-frontpage.sources']
+        for source in c.sources:
             new_updates = source.poll(global_limit, global_max_age)
             updates.extend(new_updates)
 
@@ -65,7 +68,41 @@ class FrontPageController(BaseController):
             if updates and len(updates) == global_limit:
                 global_max_age = updates[-1].time
 
+        # Find the oldest unseen item, to draw a divider after it.
+        # If this stays as None, the divider goes at the top
+        c.last_seen_item = None
+        # Could have a timestamp in the stash if this is a user, or in a cookie
+        # if this session has ever been logged out...
+        times = []
+        for source in (c.user.stash, request.cookies):
+            try:
+                times.append( int(source['frontpage-last-seen-time']) )
+            except (KeyError, ValueError):
+                pass
+
+        if times:
+            last_seen_time = datetime.datetime.fromtimestamp(max(times))
+            for update in updates:
+                if update.time > last_seen_time:
+                    c.last_seen_item = update
+                else:
+                    break
+
+        # Save ~now~ as the last-seen time
+        now = datetime.datetime.now().strftime('%s')
+        if c.user:
+            c.user.stash['frontpage-last-seen-time'] = now
+            meta.Session.add(c.user)
+        else:
+            response.set_cookie('frontpage-last-seen-time', now)
+
         # Done!  Feed to template
         c.updates = updates
 
-        return render('/index.mako')
+        ret = render('/index.mako')
+
+        # Commit AFTER rendering the template!  Committing invalidates
+        # everything in the session, undoing any eagerloading that may have
+        # been done by sources
+        meta.Session.commit()
+        return ret