Mango / utils.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

import htmlentitydefs
import logging
import os
import re
import urllib
import urllib2

from django.conf import settings

import mango
from mango.exceptions import EmptySettingError
from mango.settings import *

_formatter = logging.Formatter(
        fmt='%(asctime)s %(name)s %(levelname)-8s : %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S')

_console = logging.StreamHandler()
_console.setLevel(logging.DEBUG)
_console.setFormatter(_formatter)

_logfile = logging.FileHandler(filename=os.path.join(MANGO_PATH, 'mango.log'), encoding='utf-8')
_logfile.setLevel(logging.INFO)
_logfile.setFormatter(_formatter)

logger = logging.getLogger('mango')
logger.setLevel(logging.DEBUG)
logger.addHandler(_console)
logger.addHandler(_logfile)

def absolutize(path):
    """
    Returns the absolute path of `path`. If `path` is not (already) an absolute
    path, it is assumed to be relative to the project directory.
    
    >>> absolutize('mango/examples') == absolutize('mango/../mango/examples/')
    True
    """
    path = path.rstrip(u'/')
    if os.path.isabs(path):
        return path
    fragments = []
    head, tail = os.path.split(path)
    while tail:
        fragments.insert(0, tail)
        head, tail = os.path.split(head)
    return os.path.abspath(os.path.join(PROJECT_PATH, *fragments))

def akismet_request(kind, dict_):
    return urllib2.Request('http://%s.rest.akismet.com/1.1/%s' % (AKISMET_API_KEY, kind),
            data=urllib.urlencode([(k, v.encode('utf-8')) for k, v in dict_.items()]),
            headers={'User-Agent': 'Mango/%s' % mango.VERSION})

def canonicalize(value, dict_):
    """
    >>> d = {1: 'foo', 2: ('bar', 'baz')}
    >>> canonicalize(1, d)
    1
    >>> canonicalize('foo', d)
    1
    >>> canonicalize('baz', d)
    2
    >>> canonicalize(3, d)
    3
    """
    if value in dict_:
        return value
    for k, v in dict_.items():
        for alias in [v] if isinstance(v, basestring) else v:
            if alias == value:
                return k
    return value

def posts_directory():
    """ Creates "posts" directory if it does not already exist. """
    try:
        os.makedirs(DOCUMENTS_PATH)
    except OSError:
        if not os.path.exists(DOCUMENTS_PATH):
            raise OSError('Unable to create %s. Check permissions.' % DOCUMENTS_PATH)

def primary_author_email():
    """
    Returns the primary author's e-mail address as specified in Mango's
    settings file.
    
    >>> mango.settings.PRIMARY_AUTHOR_NAME = u'David Chambers'
    >>> mango.settings.PRIMARY_AUTHOR_EMAIL = u'david@mango.io'
    >>> primary_author_email()
    u'David Chambers <david@mango.io>'
    >>> mango.settings.PRIMARY_AUTHOR_NAME = u''
    >>> primary_author_email()
    u'david@mango.io'
    """
    name = mango.settings.PRIMARY_AUTHOR_NAME
    email = mango.settings.PRIMARY_AUTHOR_EMAIL

    if email:
        return '%s <%s>' % (name, email) if name else email

    raise EmptySettingError('PRIMARY_AUTHOR_EMAIL setting is empty',
            'Add PRIMARY_AUTHOR_EMAIL to `mango/settings/custom.py`.')

# taken from http://effbot.org/zone/re-sub.htm#unescape-html (thanks, Fredrik!)
def unescape(text):
    """
    Removes HTML or XML character references and entities from a text string.
    
    >>> unescape('E = mc&#178;')
    u'E = mc\\xb2'
    >>> unescape('Jack &amp; Jill')
    u'Jack & Jill'
    """
    def fixup(m):
        text = m.group(0)
        if text[:2] == '&#':
            # character reference
            try:
                if text[:3] == '&#x':
                    return unichr(int(text[3:-1], 16))
                else:
                    return unichr(int(text[2:-1]))
            except ValueError:
                pass
        else:
            # named entity
            try:
                text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
            except KeyError:
                pass # leave as is
        return text
    return re.sub('&#?\w+;', fixup, text)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.