Created
February 18, 2011 06:37
-
-
Save laoqiu/833341 to your computer and use it in GitHub Desktop.
flask helpers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
#coding=utf-8 | |
""" | |
helpers.py | |
~~~~~~~~~~~~~ | |
:license: BSD, see LICENSE for more details. | |
""" | |
import re | |
import markdown | |
import urlparse | |
import functools | |
from datetime import datetime | |
from flask import current_app, g | |
from flaskext.babel import gettext, ngettext | |
from flaskext.themes import render_theme_template | |
from pypress.core.extensions import cache | |
class Storage(dict): | |
""" | |
A Storage object is like a dictionary except `obj.foo` can be used | |
in addition to `obj['foo']`. | |
>>> o = storage(a=1) | |
>>> o.a | |
1 | |
>>> o['a'] | |
1 | |
>>> o.a = 2 | |
>>> o['a'] | |
2 | |
>>> del o.a | |
>>> o.a | |
Traceback (most recent call last): | |
... | |
AttributeError: 'a' | |
""" | |
def __getattr__(self, key): | |
try: | |
return self[key] | |
except KeyError, k: | |
raise AttributeError, k | |
def __setattr__(self, key, value): | |
self[key] = value | |
def __delattr__(self, key): | |
try: | |
del self[key] | |
except KeyError, k: | |
raise AttributeError, k | |
def __repr__(self): | |
return '<Storage ' + dict.__repr__(self) + '>' | |
storage = Storage | |
_punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+') | |
def slugify(text, delim=u'-'): | |
"""Generates an ASCII-only slug. From http://flask.pocoo.org/snippets/5/""" | |
result = [] | |
for word in _punct_re.split(text.lower()): | |
#word = word.encode('translit/long') | |
if word: | |
result.append(word) | |
return unicode(delim.join(result)) | |
markdown = functools.partial(markdown.markdown, | |
safe_mode='remove', | |
output_format="html") | |
cached = functools.partial(cache.cached, | |
unless= lambda: g.user is not None) | |
def get_theme(): | |
return current_app.config['THEME'] | |
def render_template(template, **context): | |
return render_theme_template(get_theme(), template, **context) | |
def timesince(dt, default=None): | |
""" | |
Returns string representing "time since" e.g. | |
3 days ago, 5 hours ago etc. | |
""" | |
if default is None: | |
default = gettext("just now") | |
now = datetime.utcnow() | |
diff = now - dt | |
years = diff.days / 365 | |
months = diff.days / 30 | |
weeks = diff.days / 7 | |
days = diff.days | |
hours = diff.seconds / 3600 | |
minutes = diff.seconds / 60 | |
seconds = diff.seconds | |
periods = ( | |
(years, ngettext("%(num)s year", "%(num)s years", num=years)), | |
(months, ngettext("%(num)s month", "%(num)s months", num=months)), | |
(weeks, ngettext("%(num)s week", "%(num)s weeks", num=weeks)), | |
(days, ngettext("%(num)s day", "%(num)s days", num=days)), | |
(hours, ngettext("%(num)s hour", "%(num)s hours", num=hours)), | |
(minutes, ngettext("%(num)s minute", "%(num)s minutes", num=minutes)), | |
(seconds, ngettext("%(num)s second", "%(num)s seconds", num=seconds)), | |
) | |
for period, trans in periods: | |
if period: | |
return gettext("%(period)s ago", period=trans) | |
return default | |
def domain(url): | |
""" | |
Returns the domain of a URL e.g. http://reddit.com/ > reddit.com | |
""" | |
rv = urlparse.urlparse(url).netloc | |
if rv.startswith("www."): | |
rv = rv[4:] | |
return rv | |
def endtags(html): | |
""" close all open html tags at the end of the string """ | |
NON_CLOSING_TAGS = ['AREA', 'BASE', 'BASEFONT', 'BR', 'COL', 'FRAME', | |
'HR', 'IMG', 'INPUT', 'ISINDEX', 'LINK', 'META', 'PARAM'] | |
opened_tags = re.findall(r"<([a-z]+)[^<>]*>",html) | |
closed_tags = re.findall(r"</([a-z]+)>",html) | |
opened_tags = [i.lower() for i in opened_tags if i.upper() not in NON_CLOSING_TAGS] | |
closed_tags = [i.lower() for i in closed_tags] | |
len_opened = len(opened_tags) | |
if len_opened==len(closed_tags): | |
return html | |
opened_tags.reverse() | |
for tag in opened_tags: | |
if tag in closed_tags: | |
closed_tags.remove(tag) | |
else: | |
html += "</%s>" % tag | |
return html | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment