Skip to content

Commit

Permalink
Merge 6449f09 into c6306c7
Browse files Browse the repository at this point in the history
  • Loading branch information
Bibhas committed Mar 25, 2019
2 parents c6306c7 + 6449f09 commit 4ef24da
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 13 deletions.
1 change: 1 addition & 0 deletions baseframe/__init__.py
Expand Up @@ -374,6 +374,7 @@ def process_response(response):
b__ = __
from flask_babelex import gettext as _, lazy_gettext as __

from .utils import * # NOQA
from .views import * # NOQA
from .errors import * # NOQA
from .filters import * # NOQA
Expand Down
40 changes: 37 additions & 3 deletions baseframe/filters.py
@@ -1,22 +1,24 @@
# -*- coding: utf-8 -*-

import os
from datetime import datetime
from datetime import datetime, timedelta
from flask import Markup, request
from pytz import utc
import six

from coaster.utils import md5sum
from coaster.gfm import markdown
from coaster.utils import text_blocks

from . import b_ as _, cache
from . import baseframe, current_app
from . import baseframe, current_app, get_timezone
from .utils import request_timestamp
from .views import ext_assets


@baseframe.app_template_filter('age')
def age(dt):
delta = datetime.utcnow() - dt
delta = request_timestamp() - dt
if delta.days == 0:
# < 1 day
if delta.seconds < 1:
Expand Down Expand Up @@ -166,3 +168,35 @@ def cdata(text):
Convert text to a CDATA sequence
"""
return Markup('<![CDATA[' + text.replace(']]>', ']]]]><![CDATA[>') + ']]>')


@baseframe.app_template_filter('shortdate')
def shortdate(value):
if isinstance(value, datetime):
tz = get_timezone()
if value.tzinfo is None:
dt = utc.localize(value).astimezone(tz)
else:
dt = value.astimezone(tz)
utc_now = utc.localize(request_timestamp()).astimezone(tz)
else:
dt = value
utc_now = request_timestamp().date()
if dt > (utc_now - timedelta(days=int(current_app.config.get('SHORTDATE_THRESHOLD_DAYS', 0)))):
return dt.strftime('%e %b')
else:
# The string replace hack is to deal with inconsistencies in the underlying
# implementation of strftime. See https://bugs.python.org/issue8304
return six.text_type(dt.strftime("%e %b '%y")).replace(u"'", u"’")


@baseframe.app_template_filter('longdate')
def longdate(value):
if isinstance(value, datetime):
if value.tzinfo is None:
dt = utc.localize(value).astimezone(get_timezone())
else:
dt = value.astimezone(get_timezone())
else:
dt = value
return dt.strftime('%e %B %Y')
6 changes: 3 additions & 3 deletions baseframe/forms/fields.py
@@ -1,12 +1,11 @@
# -*- coding: utf-8 -*-

from datetime import datetime
from decimal import Decimal, InvalidOperation as DecimalError
from six.moves.urllib.parse import urljoin
from pytz import utc, timezone as pytz_timezone
from flask import current_app
import wtforms
from wtforms.fields import SelectField as SelectFieldBase, SelectMultipleField, SubmitField, FileField
from wtforms.fields import SelectField as SelectFieldBase, SelectMultipleField, SubmitField, FileField # NOQA
from wtforms.widgets import Select as OriginalSelectWidget
from wtforms.compat import text_type
from wtforms.utils import unset_value
Expand All @@ -15,6 +14,7 @@
import six

from .. import _, get_timezone
from ..utils import request_timestamp
from .widgets import TinyMce3, TinyMce4, DateTimeInput, CoordinatesInput, RadioMatrixInput, SelectWidget, Select2Widget
from .parsleyjs import TextAreaField, StringField, URLField

Expand Down Expand Up @@ -288,7 +288,7 @@ def timezone(self, value):
else:
self.tz = value
self._timezone = self.tz.zone
now = utc.localize(datetime.utcnow()).astimezone(self.tz)
now = utc.localize(request_timestamp()).astimezone(self.tz)
self.tzname = now.tzname()
self.is_dst = bool(now.dst())

Expand Down
20 changes: 19 additions & 1 deletion baseframe/utils.py
@@ -1,13 +1,31 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import

from datetime import datetime

import six
from six.moves.urllib.parse import quote as urlquote

from flask import g

from mxsniff import mxsniff, MXLookupException

from . import asset_cache

__all__ = ['is_public_email_domain']
__all__ = ['request_timestamp', 'is_public_email_domain']


def request_timestamp():
"""
Return a UTC timestamp for the request
"""
if not g:
return datetime.utcnow()
ts = getattr(g, 'request_timestamp', None)
if ts is None:
ts = datetime.utcnow()
g.request_timestamp = ts
return ts


def is_public_email_domain(email_or_domain, default=None, timeout=30):
Expand Down
13 changes: 7 additions & 6 deletions baseframe/views.py
Expand Up @@ -2,7 +2,7 @@

import os
import requests
from datetime import datetime, timedelta
from datetime import timedelta
from six.moves.urllib.parse import urlparse, urljoin
from flask import current_app, send_from_directory, render_template, abort, request
from flask_assets import Bundle
Expand All @@ -11,14 +11,15 @@
from coaster.assets import split_namespec
from coaster.views import render_with
from . import baseframe, networkbar_cache, asset_cache, assets as assets_repo
from .utils import request_timestamp


@networkbar_cache.cached(key_prefix='networkbar_links')
def networkbar_links_fetcher():
try:
r = requests.get(current_app.config['NETWORKBAR_DATA'])
return (r.json() if callable(r.json) else r.json).get('links', [])
except: # Catch all exceptions
except: # Catch all exceptions # NOQA
return []


Expand Down Expand Up @@ -155,15 +156,15 @@ def toastr_messages_js(subdomain=None):
def editorcss(subdomain=None):
response = current_app.response_class(render_template('editor.css.jinja2'),
mimetype='text/css',
headers={'Expires': (datetime.utcnow() + timedelta(minutes=60)).strftime('%a, %d %b %Y %H:%M:%S GMT')})
headers={'Expires': (request_timestamp() + timedelta(minutes=60)).strftime('%a, %d %b %Y %H:%M:%S GMT')})
return response


@baseframe.route('/api/baseframe/1/csrf/refresh', subdomain='<subdomain>')
@baseframe.route('/api/baseframe/1/csrf/refresh', defaults={'subdomain': None})
@render_with({
'text/plain': lambda r: r['csrf_token'],
}, json=True, jsonp=False)
}, json=True, jsonp=False)
def csrf_refresh(subdomain=None):
parsed_host = urlparse(request.url_root)
origin = parsed_host.scheme + u'://' + parsed_host.netloc
Expand All @@ -176,5 +177,5 @@ def csrf_refresh(subdomain=None):
return {'csrf_token': generate_csrf()}, 200, {
'Access-Control-Allow-Origin': origin,
'Vary': 'Origin',
'Expires': (datetime.utcnow() + timedelta(minutes=10)).strftime('%a, %d %b %Y %H:%M:%S GMT')
}
'Expires': (request_timestamp() + timedelta(minutes=10)).strftime('%a, %d %b %Y %H:%M:%S GMT')
}
44 changes: 44 additions & 0 deletions tests/test_filters.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-

from datetime import datetime, timedelta
from pytz import utc

from coaster.utils import md5sum
from baseframe import filters, forms
Expand Down Expand Up @@ -142,3 +143,46 @@ def test_none_if_empty(self):
self.assertEqual(none_if_empty_func([]), None)
self.assertEqual(none_if_empty_func(False), None)
self.assertEqual(none_if_empty_func(0), None)

def test_shortdate_date_with_threshold(self):
self.app.config['SHORTDATE_THRESHOLD_DAYS'] = 10
testdate = self.now.date() - timedelta(days=5)
with self.app.test_request_context('/'):
assert filters.shortdate(testdate) == testdate.strftime('%e %b')

def test_shortdate_date_without_threshold(self):
self.app.config['SHORTDATE_THRESHOLD_DAYS'] = 0
testdate = self.now.date() - timedelta(days=5)
with self.app.test_request_context('/'):
assert filters.shortdate(testdate).replace(u"’", u"'") == testdate.strftime("%e %b '%y")

def test_shortdate_datetime_with_threshold(self):
self.app.config['SHORTDATE_THRESHOLD_DAYS'] = 10
testdate = self.now - timedelta(days=5)
with self.app.test_request_context('/'):
assert filters.shortdate(testdate) == testdate.strftime('%e %b')

def test_shortdate_datetime_without_threshold(self):
testdate = self.now - timedelta(days=5)
with self.app.test_request_context('/'):
assert filters.shortdate(testdate).replace(u"’", u"'") == testdate.strftime("%e %b '%y")

def test_shortdate_datetime_with_tz(self):
testdate = utc.localize(self.now)
with self.app.test_request_context('/'):
assert filters.shortdate(testdate).replace(u"’", u"'") == testdate.strftime("%e %b '%y")

def test_longdate_date(self):
testdate = self.now.date()
with self.app.test_request_context('/'):
assert filters.longdate(testdate) == testdate.strftime('%e %B %Y')

def test_longdate_datetime(self):
testdate = self.now
with self.app.test_request_context('/'):
assert filters.longdate(testdate) == testdate.strftime('%e %B %Y')

def test_longdate_datetime_with_tz(self):
testdate = utc.localize(self.now)
with self.app.test_request_context('/'):
assert filters.longdate(testdate) == testdate.strftime('%e %B %Y')

0 comments on commit 4ef24da

Please sign in to comment.