Source code for atmo.news.views

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at http://mozilla.org/MPL/2.0/.
import os

import CommonMark
from django.conf import settings
from django.http import HttpResponse
from django.shortcuts import render
from django.utils.functional import cached_property
from pkg_resources import parse_version


[docs]class News: """ Encapsulate the rendering of the news document ``NEWS.md``. """ def __init__(self): self.path = os.path.join(settings.BASE_DIR, 'NEWS.md') self.parser = CommonMark.Parser() self.renderer = CommonMark.HtmlRenderer() self.cookie_name = 'news_current' @cached_property def ast(self): """ Return (and cache for repeated querying) the Markdown AST of the ``NEWS.md`` file. """ with open(self.path, 'r') as news_file: content = news_file.read() return self.parser.parse(content) @cached_property def latest(self): """ Return the latest version found in the ``NEWS.md`` file. """ version = self.ast.first_child.literal if not version: version = self.ast.first_child.first_child.literal if not version: version = '0.0' return version
[docs] def render(self): "Render the ``NEWS.md`` file as a HTML." return self.renderer.render(self.ast)
[docs] def update(self, request, response): "Set the cookie for the given request with the latest seen version." if not self.uptodate(request): response.set_cookie(self.cookie_name, self.latest, secure=True, httponly=True)
[docs] def current(self, request): "Return the latest seen version or nothing." return request.COOKIES.get(self.cookie_name) or ''
[docs] def uptodate(self, request): "Return whether the current is newer than the last seen version." return parse_version(self.latest) <= parse_version(self.current(request))
[docs]def list_news(request): """ View to list all news and optionally render only part of the template for AJAX requests. """ news = News() if request.is_ajax(): response = HttpResponse(news.render()) else: context = {'news': news} response = render(request, 'atmo/news/list.html', context) news.update(request, response) return response
[docs]def check_news(request): """ View to check if the current user has seen the latest "News" section and return either `'ok'` or `'meh'` as a string. """ news = News() if news.uptodate(request): return HttpResponse('ok') else: return HttpResponse('meh')