From 4dabac44a463e885571db1c4799c452dd651bfbd Mon Sep 17 00:00:00 2001 From: Rizmari Versfeld Date: Fri, 22 May 2015 17:43:56 +0200 Subject: [PATCH 01/11] override home view to add recent_content to context --- development.ini | 5 +++ springboard_iogt/application.py | 5 +++ springboard_iogt/templates/home.jinja2 | 35 +++++---------- springboard_iogt/views.py | 60 ++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 25 deletions(-) create mode 100644 springboard_iogt/views.py diff --git a/development.ini b/development.ini index f3f963f..22c50dc 100644 --- a/development.ini +++ b/development.ini @@ -6,6 +6,11 @@ unicore.content_repo_urls = https://github.com/universalcore/unicore-cms-content https://github.com/universalcore/unicore-cms-content-mariestopes-za-qa https://github.com/universalcore/unicore-cms-content-ureport-za-qa +cache.regions = minute, hour +cache.type = memory +cache.minute.expire = 60 +cache.hour.expire = 3600 + [celery] celery_task_serializer = json celery_always_eager = True diff --git a/springboard_iogt/application.py b/springboard_iogt/application.py index 1694536..87ea382 100644 --- a/springboard_iogt/application.py +++ b/springboard_iogt/application.py @@ -13,6 +13,11 @@ def main(global_config, **settings): defaults.update(settings) config = Configurator(settings=defaults) + + # override springboard routes + config.add_route('home', '/') + config.scan('.views') + config.include('springboard.config') config.override_asset( to_override='springboard:templates/', diff --git a/springboard_iogt/templates/home.jinja2 b/springboard_iogt/templates/home.jinja2 index 48a3554..8fbf4ce 100644 --- a/springboard_iogt/templates/home.jinja2 +++ b/springboard_iogt/templates/home.jinja2 @@ -15,41 +15,26 @@ - {% set featured_pages = all_pages.filter(language=language, featured=True) %} - {% if featured_pages %} -
-
{{gettext('Latest')}}
- {% for page in featured_pages %} + {% for category, page in recent_content %} +
+ {% if category %} + + {% endif %}

{{page.description}}

- {% endfor %} -
- {% endif %} - - {% for category in all_categories.filter(language=language) %} - {% set category_pages = all_pages.filter(primary_category=category.uuid) %} - {% if category_pages %} -
- - {% for page in category_pages %} -
- -

{{page.description}}

-
-
- {% endfor %}
+ {% if category %} + {% endif %}
- {% endif %} {% endfor %}
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/springboard_iogt/views.py b/springboard_iogt/views.py new file mode 100644 index 0000000..06bd684 --- /dev/null +++ b/springboard_iogt/views.py @@ -0,0 +1,60 @@ +from random import randint, shuffle + +from pyramid.view import view_config +from beaker.cache import cache_region +from elasticutils import F + +from springboard.views.base import SpringboardViews + + +HOUR_CACHE_REGION = 'hour' + + +class IoGTViews(SpringboardViews): + + @view_config(route_name='home', + renderer='springboard_iogt:templates/home.jinja2') + def index_view(self): + return self.context( + recent_content=self.recent_content()) + + @cache_region(HOUR_CACHE_REGION) + def _recent_content(self, language, limit): + categories = self.all_categories.filter( + language=language).everything() + + def get_category_object(uuid): + if not uuid: + return None + [category] = filter(lambda c: c.uuid == uuid, categories) + return category + + # get 2 most recent pages + [page1, page2] = self.all_pages.filter( + language=self.language).order_by('-created_at')[:2] + category1 = get_category_object(page1.primary_category) + category2 = get_category_object(page2.primary_category) + + # get most recent page per category + # exclude the 2 most recent overall + content = [] + f = ~F(uuid=page1.uuid) & ~F(uuid=page2.uuid) + for category in categories: + try: + f_cat = F(primary_category=category.uuid) + [page] = self.all_pages.filter(f & f_cat).order_by( + '-created_at')[:1] + content.append((category, page)) + except ValueError: + pass + + shuffle(content) + content = content[:limit - 2] + content.insert(randint(0, len(content)), (category1, page1)) + content.insert(randint(0, len(content)), (category2, page2)) + return content + + def recent_content(self, limit=8): + content = self._recent_content(self.language, limit) + content = [(c.to_object(), p.to_object()) for c, p in content] + return content From e59ffe88300cfda94a241e6254f2df00b65e9a22 Mon Sep 17 00:00:00 2001 From: Rizmari Versfeld Date: Fri, 22 May 2015 17:45:31 +0200 Subject: [PATCH 02/11] use springboard feature branch for now --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 26c7d07..d72c159 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -springboard \ No newline at end of file +-e git+git@github.com:universalcore/springboard.git@985237bab3fc4b1eb50faa9c2e05d98d906a0938#egg=springboard-feature/issue-27-make-view-logic-reusable From 5353fff8119733bebb24a351da4a138e466395c6 Mon Sep 17 00:00:00 2001 From: Rizmari Versfeld Date: Fri, 22 May 2015 17:50:18 +0200 Subject: [PATCH 03/11] correct pip git url format --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d72c159..eca01f0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ --e git+git@github.com:universalcore/springboard.git@985237bab3fc4b1eb50faa9c2e05d98d906a0938#egg=springboard-feature/issue-27-make-view-logic-reusable +-e git+https://github.com/universalcore/springboard.git@feature/issue-27-make-view-logic-reusable From 28bc0c13a9435eedbd19393ce5df624a7dc43d86 Mon Sep 17 00:00:00 2001 From: Rizmari Versfeld Date: Fri, 22 May 2015 17:52:21 +0200 Subject: [PATCH 04/11] and again --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index eca01f0..d55eded 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ --e git+https://github.com/universalcore/springboard.git@feature/issue-27-make-view-logic-reusable +-e git+https://github.com/universalcore/springboard.git@feature/issue-27-make-view-logic-reusable#egg=springboard-feature/issue-27-make-view-logic-reusable From e084bb111bfe15bf6c03b977e6f81f06a18d2d9c Mon Sep 17 00:00:00 2001 From: Rizmari Versfeld Date: Fri, 22 May 2015 17:57:05 +0200 Subject: [PATCH 05/11] and hopefully the last time --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d55eded..241e1d0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ --e git+https://github.com/universalcore/springboard.git@feature/issue-27-make-view-logic-reusable#egg=springboard-feature/issue-27-make-view-logic-reusable +-e git+https://github.com/universalcore/springboard.git@feature/issue-27-make-view-logic-reusable#egg=springboard-feature-issue-27-make-view-logic-reusable From 072e6b444b638ac21f720fdf71455beadc9e7cf0 Mon Sep 17 00:00:00 2001 From: Rizmari Versfeld Date: Fri, 22 May 2015 18:09:42 +0200 Subject: [PATCH 06/11] simplify --- springboard_iogt/views.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/springboard_iogt/views.py b/springboard_iogt/views.py index 06bd684..a951c15 100644 --- a/springboard_iogt/views.py +++ b/springboard_iogt/views.py @@ -15,11 +15,12 @@ class IoGTViews(SpringboardViews): @view_config(route_name='home', renderer='springboard_iogt:templates/home.jinja2') def index_view(self): - return self.context( - recent_content=self.recent_content()) + content = self.recent_content(self.language, 8) + content = [(c.to_object(), p.to_object()) for c, p in content] + return self.context(recent_content=content) @cache_region(HOUR_CACHE_REGION) - def _recent_content(self, language, limit): + def recent_content(self, language, limit): categories = self.all_categories.filter( language=language).everything() @@ -53,8 +54,3 @@ def get_category_object(uuid): content.insert(randint(0, len(content)), (category1, page1)) content.insert(randint(0, len(content)), (category2, page2)) return content - - def recent_content(self, limit=8): - content = self._recent_content(self.language, limit) - content = [(c.to_object(), p.to_object()) for c, p in content] - return content From 79487fed1f47482c84308f2e366eb32cfdae830a Mon Sep 17 00:00:00 2001 From: Rizmari Versfeld Date: Mon, 25 May 2015 15:39:24 +0200 Subject: [PATCH 07/11] remove caching --- development.ini | 5 ----- springboard_iogt/views.py | 5 ----- 2 files changed, 10 deletions(-) diff --git a/development.ini b/development.ini index 22c50dc..f3f963f 100644 --- a/development.ini +++ b/development.ini @@ -6,11 +6,6 @@ unicore.content_repo_urls = https://github.com/universalcore/unicore-cms-content https://github.com/universalcore/unicore-cms-content-mariestopes-za-qa https://github.com/universalcore/unicore-cms-content-ureport-za-qa -cache.regions = minute, hour -cache.type = memory -cache.minute.expire = 60 -cache.hour.expire = 3600 - [celery] celery_task_serializer = json celery_always_eager = True diff --git a/springboard_iogt/views.py b/springboard_iogt/views.py index a951c15..4823ccc 100644 --- a/springboard_iogt/views.py +++ b/springboard_iogt/views.py @@ -1,15 +1,11 @@ from random import randint, shuffle from pyramid.view import view_config -from beaker.cache import cache_region from elasticutils import F from springboard.views.base import SpringboardViews -HOUR_CACHE_REGION = 'hour' - - class IoGTViews(SpringboardViews): @view_config(route_name='home', @@ -19,7 +15,6 @@ def index_view(self): content = [(c.to_object(), p.to_object()) for c, p in content] return self.context(recent_content=content) - @cache_region(HOUR_CACHE_REGION) def recent_content(self, language, limit): categories = self.all_categories.filter( language=language).everything() From a128bf7fc36bbb3826eac9d14aa964ec88ae2b72 Mon Sep 17 00:00:00 2001 From: Rizmari Versfeld Date: Mon, 25 May 2015 18:44:09 +0200 Subject: [PATCH 08/11] use 1 query to get random categories, use seed for hourly changes --- springboard_iogt/templates/home.jinja2 | 2 +- springboard_iogt/utils.py | 8 ++++ springboard_iogt/views.py | 64 ++++++++++++++------------ 3 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 springboard_iogt/utils.py diff --git a/springboard_iogt/templates/home.jinja2 b/springboard_iogt/templates/home.jinja2 index 8fbf4ce..d7963a7 100644 --- a/springboard_iogt/templates/home.jinja2 +++ b/springboard_iogt/templates/home.jinja2 @@ -15,7 +15,7 @@ - {% for category, page in recent_content %} + {% for category, page in recent_content(limit=8) %}
{% if category %}
diff --git a/springboard_iogt/utils.py b/springboard_iogt/utils.py new file mode 100644 index 0000000..ae9b7de --- /dev/null +++ b/springboard_iogt/utils.py @@ -0,0 +1,8 @@ +def randomize_query(s_obj, seed=None): + return s_obj.query_raw({ + "function_score": { + "functions": [ + {"random_score": {"seed": seed}} + ], + "score_mode": "sum" + }}) diff --git a/springboard_iogt/views.py b/springboard_iogt/views.py index 4823ccc..44ca4c1 100644 --- a/springboard_iogt/views.py +++ b/springboard_iogt/views.py @@ -1,51 +1,55 @@ -from random import randint, shuffle +from datetime import datetime +from itertools import chain from pyramid.view import view_config from elasticutils import F from springboard.views.base import SpringboardViews +from springboard_iogt.utils import randomize_query + class IoGTViews(SpringboardViews): @view_config(route_name='home', renderer='springboard_iogt:templates/home.jinja2') def index_view(self): - content = self.recent_content(self.language, 8) - content = [(c.to_object(), p.to_object()) for c, p in content] - return self.context(recent_content=content) - - def recent_content(self, language, limit): - categories = self.all_categories.filter( - language=language).everything() - - def get_category_object(uuid): - if not uuid: - return None - [category] = filter(lambda c: c.uuid == uuid, categories) - return category + return self.context(recent_content=self.recent_content()) + def recent_content(self): # get 2 most recent pages [page1, page2] = self.all_pages.filter( language=self.language).order_by('-created_at')[:2] - category1 = get_category_object(page1.primary_category) - category2 = get_category_object(page2.primary_category) + [category1] = (self.all_categories.filter(uuid=page1.primary_category) + if page1.primary_category + else None) + [category2] = (self.all_categories.filter(uuid=page2.primary_category) + if page2.primary_category + else None) + most_recent = [(category1, page1), (category2, page2)] + + # random seed that changes hourly + seed = datetime.utcnow().replace( + minute=0, second=0, microsecond=0) + seed = (seed - datetime.utcfromtimestamp(0)).total_seconds() + seed = int(seed) # get most recent page per category # exclude the 2 most recent overall - content = [] f = ~F(uuid=page1.uuid) & ~F(uuid=page2.uuid) - for category in categories: - try: - f_cat = F(primary_category=category.uuid) - [page] = self.all_pages.filter(f & f_cat).order_by( + categories = self.all_categories.filter( + f, language=self.language) + categories = randomize_query(categories, seed=seed) + + def do_query(limit): + most_recent_per_category = [] + for category in categories[:limit - 2]: + [page] = self.all_pages.filter( + f, primary_category=category.uuid).order_by( '-created_at')[:1] - content.append((category, page)) - except ValueError: - pass - - shuffle(content) - content = content[:limit - 2] - content.insert(randint(0, len(content)), (category1, page1)) - content.insert(randint(0, len(content)), (category2, page2)) - return content + most_recent_per_category.append((category, page)) + + return [(c.to_object(), p.to_object()) for c, p + in chain(most_recent, most_recent_per_category)] + + return do_query From ce99bbfa016542ebbc2c53b0bf5485cb852d7652 Mon Sep 17 00:00:00 2001 From: Rizmari Versfeld Date: Tue, 26 May 2015 12:38:58 +0200 Subject: [PATCH 09/11] fixes and fewer queries --- requirements.txt | 2 +- springboard_iogt/tests/__init__.py | 0 springboard_iogt/tests/test_views.py | 53 ++++++++++++++++++++++++++++ springboard_iogt/views.py | 51 ++++++++++++++++---------- 4 files changed, 87 insertions(+), 19 deletions(-) create mode 100644 springboard_iogt/tests/__init__.py create mode 100644 springboard_iogt/tests/test_views.py diff --git a/requirements.txt b/requirements.txt index 241e1d0..18d0948 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ --e git+https://github.com/universalcore/springboard.git@feature/issue-27-make-view-logic-reusable#egg=springboard-feature-issue-27-make-view-logic-reusable +springboard>=1.0.0 diff --git a/springboard_iogt/tests/__init__.py b/springboard_iogt/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/springboard_iogt/tests/test_views.py b/springboard_iogt/tests/test_views.py new file mode 100644 index 0000000..f653222 --- /dev/null +++ b/springboard_iogt/tests/test_views.py @@ -0,0 +1,53 @@ +from datetime import datetime, timedelta + +from pyramid import testing + +from springboard.tests import SpringboardTestCase + +from springboard_iogt.views import IoGTViews + + +class TestIoGTViews(SpringboardTestCase): + + def setUp(self): + self.workspace = self.mk_workspace() + self.config = testing.setUp(settings={ + 'unicore.repos_dir': self.working_dir, + 'unicore.content_repo_urls': self.workspace.working_dir, + }) + + def tearDown(self): + testing.tearDown() + + def test_recent_content(self): + category_p1, category_p3 = self.mk_categories(self.workspace, count=2) + [page1] = self.mk_pages( + self.workspace, count=1, + primary_category=category_p1.uuid, + created_at=datetime.utcnow().isoformat()) + [page2] = self.mk_pages( + self.workspace, count=1, + primary_category=None, + created_at=(datetime.utcnow() - timedelta(hours=1)).isoformat()) + [page3] = self.mk_pages( + self.workspace, count=1, + primary_category=category_p3.uuid, + created_at=(datetime.utcnow() - timedelta(hours=2)).isoformat()) + views = IoGTViews(self.mk_request()) + + for i in range(5): + results = views.recent_content()(limit=2) + self.assertEqual(len(results), 2) + self.assertEqual( + {(category_p1.uuid, page1.uuid), (None, page2.uuid)}, + set((c.uuid if c else None, p.uuid) for c, p in results)) + for i in range(5): + results = views.recent_content()(limit=3) + self.assertEqual(len(results), 3) + self.assertEqual( + {(category_p1.uuid, page1.uuid), (None, page2.uuid), + (category_p3.uuid, page3.uuid)}, + set((c.uuid if c else None, p.uuid) for c, p in results)) + + def test_index_view(self): + pass diff --git a/springboard_iogt/views.py b/springboard_iogt/views.py index 44ca4c1..30b9f73 100644 --- a/springboard_iogt/views.py +++ b/springboard_iogt/views.py @@ -1,3 +1,4 @@ +import random from datetime import datetime from itertools import chain @@ -17,16 +18,17 @@ def index_view(self): return self.context(recent_content=self.recent_content()) def recent_content(self): - # get 2 most recent pages + # get 2 most recent pages and their categories [page1, page2] = self.all_pages.filter( language=self.language).order_by('-created_at')[:2] - [category1] = (self.all_categories.filter(uuid=page1.primary_category) - if page1.primary_category - else None) - [category2] = (self.all_categories.filter(uuid=page2.primary_category) - if page2.primary_category - else None) - most_recent = [(category1, page1), (category2, page2)] + categories = self.all_categories.filter( + uuid__in=filter(lambda uuid: uuid is not None, + [page1.primary_category, page2.primary_category])) + categories = dict((category.uuid, category) for category in categories) + category1 = (categories[page1.primary_category] + if page1.primary_category else None) + category2 = (categories[page2.primary_category] + if page2.primary_category else None) # random seed that changes hourly seed = datetime.utcnow().replace( @@ -34,22 +36,35 @@ def recent_content(self): seed = (seed - datetime.utcfromtimestamp(0)).total_seconds() seed = int(seed) - # get most recent page per category - # exclude the 2 most recent overall - f = ~F(uuid=page1.uuid) & ~F(uuid=page2.uuid) + # get random categories and exclude categories of 2 most recent pages categories = self.all_categories.filter( - f, language=self.language) + ~F(uuid__in=categories.keys()), language=self.language) categories = randomize_query(categories, seed=seed) + # filter to exclude the 2 most recent pages + f_exclude_pages = ~F(uuid__in=[page1.uuid, page2.uuid]) def do_query(limit): + most_recent = [(category1, page1), (category2, page2)] most_recent_per_category = [] + # NOTE: this is bad if limit is large + # We are fetching pages individually, because we + # can't use facets or aggregates. for category in categories[:limit - 2]: - [page] = self.all_pages.filter( - f, primary_category=category.uuid).order_by( - '-created_at')[:1] - most_recent_per_category.append((category, page)) + try: + [page] = self.all_pages.filter( + f_exclude_pages, + primary_category=category.uuid).order_by( + '-created_at')[:1] + most_recent_per_category.append((category, page)) + except ValueError: + pass - return [(c.to_object(), p.to_object()) for c, p - in chain(most_recent, most_recent_per_category)] + results = [(cat.to_object() if cat else None, page.to_object()) + for cat, page + in chain(most_recent, most_recent_per_category)] + # randomize position of most_recent content + random.seed(seed) + random.shuffle(results) + return results return do_query From 9b2b74cf856ff44b0a09b5d2528e78d73798f792 Mon Sep 17 00:00:00 2001 From: Rizmari Versfeld Date: Tue, 26 May 2015 13:11:11 +0200 Subject: [PATCH 10/11] test index view, fix pep8 --- springboard_iogt/tests/test_views.py | 21 ++++++++++++++++++++- springboard_iogt/views.py | 4 ++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/springboard_iogt/tests/test_views.py b/springboard_iogt/tests/test_views.py index f653222..46efe2c 100644 --- a/springboard_iogt/tests/test_views.py +++ b/springboard_iogt/tests/test_views.py @@ -1,3 +1,5 @@ +import re + from datetime import datetime, timedelta from pyramid import testing @@ -5,6 +7,7 @@ from springboard.tests import SpringboardTestCase from springboard_iogt.views import IoGTViews +from springboard_iogt.application import main class TestIoGTViews(SpringboardTestCase): @@ -35,6 +38,7 @@ def test_recent_content(self): created_at=(datetime.utcnow() - timedelta(hours=2)).isoformat()) views = IoGTViews(self.mk_request()) + # repeat a few times because of randomness for i in range(5): results = views.recent_content()(limit=2) self.assertEqual(len(results), 2) @@ -50,4 +54,19 @@ def test_recent_content(self): set((c.uuid if c else None, p.uuid) for c, p in results)) def test_index_view(self): - pass + [category] = self.mk_categories(self.workspace, count=1) + [page1, page2] = self.mk_pages( + self.workspace, count=2, + created_at=datetime.utcnow().isoformat()) + page1 = page1.update({'primary_category': category.uuid}) + self.workspace.save(page1, 'Update page category') + self.workspace.refresh_index() + app = self.mk_app(self.workspace, main=main) + + response = app.get('/') + self.assertEqual(response.status_int, 200) + html = response.html + re_page_url = re.compile(r'/page/.{32}/') + re_category_url = re.compile(r'/category/.{32}/') + self.assertEqual(len(html.find_all('a', href=re_page_url)), 2) + self.assertEqual(len(html.find_all('a', href=re_category_url)), 2) diff --git a/springboard_iogt/views.py b/springboard_iogt/views.py index 30b9f73..af31a1f 100644 --- a/springboard_iogt/views.py +++ b/springboard_iogt/views.py @@ -59,8 +59,8 @@ def do_query(limit): except ValueError: pass - results = [(cat.to_object() if cat else None, page.to_object()) - for cat, page + results = [(c.to_object() if c else None, p.to_object()) + for c, p in chain(most_recent, most_recent_per_category)] # randomize position of most_recent content random.seed(seed) From 01d33214810993b4b2ecca042047ee3f54a7ee5b Mon Sep 17 00:00:00 2001 From: Rizmari Versfeld Date: Tue, 26 May 2015 14:17:51 +0200 Subject: [PATCH 11/11] style improvements --- springboard_iogt/tests/test_views.py | 26 ++++++++++++-------------- springboard_iogt/views.py | 15 +++++---------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/springboard_iogt/tests/test_views.py b/springboard_iogt/tests/test_views.py index 46efe2c..9fa88f6 100644 --- a/springboard_iogt/tests/test_views.py +++ b/springboard_iogt/tests/test_views.py @@ -38,20 +38,18 @@ def test_recent_content(self): created_at=(datetime.utcnow() - timedelta(hours=2)).isoformat()) views = IoGTViews(self.mk_request()) - # repeat a few times because of randomness - for i in range(5): - results = views.recent_content()(limit=2) - self.assertEqual(len(results), 2) - self.assertEqual( - {(category_p1.uuid, page1.uuid), (None, page2.uuid)}, - set((c.uuid if c else None, p.uuid) for c, p in results)) - for i in range(5): - results = views.recent_content()(limit=3) - self.assertEqual(len(results), 3) - self.assertEqual( - {(category_p1.uuid, page1.uuid), (None, page2.uuid), - (category_p3.uuid, page3.uuid)}, - set((c.uuid if c else None, p.uuid) for c, p in results)) + results = views.recent_content()(limit=2) + self.assertEqual(len(results), 2) + self.assertEqual( + {(category_p1.uuid, page1.uuid), (None, page2.uuid)}, + set((c.uuid if c else None, p.uuid) for c, p in results)) + + results = views.recent_content()(limit=3) + self.assertEqual(len(results), 3) + self.assertEqual( + {(category_p1.uuid, page1.uuid), (None, page2.uuid), + (category_p3.uuid, page3.uuid)}, + set((c.uuid if c else None, p.uuid) for c, p in results)) def test_index_view(self): [category] = self.mk_categories(self.workspace, count=1) diff --git a/springboard_iogt/views.py b/springboard_iogt/views.py index af31a1f..dfe3418 100644 --- a/springboard_iogt/views.py +++ b/springboard_iogt/views.py @@ -22,19 +22,14 @@ def recent_content(self): [page1, page2] = self.all_pages.filter( language=self.language).order_by('-created_at')[:2] categories = self.all_categories.filter( - uuid__in=filter(lambda uuid: uuid is not None, - [page1.primary_category, page2.primary_category])) + uuid__in=filter( + None, [page1.primary_category, page2.primary_category])) categories = dict((category.uuid, category) for category in categories) - category1 = (categories[page1.primary_category] - if page1.primary_category else None) - category2 = (categories[page2.primary_category] - if page2.primary_category else None) + category1 = categories.get(page1.primary_category) + category2 = categories.get(page2.primary_category) # random seed that changes hourly - seed = datetime.utcnow().replace( - minute=0, second=0, microsecond=0) - seed = (seed - datetime.utcfromtimestamp(0)).total_seconds() - seed = int(seed) + seed = datetime.utcnow().hour # get random categories and exclude categories of 2 most recent pages categories = self.all_categories.filter(