Skip to content

Instantly share code, notes, and snippets.

@laoqiu
Created February 18, 2011 06:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save laoqiu/833341 to your computer and use it in GitHub Desktop.
Save laoqiu/833341 to your computer and use it in GitHub Desktop.
flask helpers
#!/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