Source

Mango / utils.py

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

import os
import re

from django.conf import settings
from django.core.cache import cache

from mango.models import Document
from mango.settings import *

def get_document(filepath):
    """
    Returns a Document object. First an attempt is made to retrieve the object
    from the cache; if this fails a new Document object is created and cached.
    
    >>> get_document('mango/examples/1=>my-first-post.text').html
    u"\\n<p>Welcome to Mango. ... <strong>Congratulations!</strong></p>"
    """
    if not os.path.isabs(filepath):
        filepath = os.path.join(PROJECT_PATH, filepath)

    document, mod_time = cache.get(filepath, (None, None)) # retrieve Document
    if document and mod_time == os.path.getmtime(filepath):
        if settings.DEBUG:
            print 'Document retrieved from cache: %s' % filepath
    else: # modified or not in cache, so create and cache a new Document object
        f = open(filepath)
        contents = unicode(f.read(), 'utf-8')
        f.close()
        document = Document(contents)
        document.convert().set_urls(filepath)
        cache.set(filepath, (document, os.path.getmtime(filepath)),
                POST_CACHE_SECONDS)
        if settings.DEBUG:
            print 'Document created and cached: %s' % filepath

    return document

def get_documents(path_to_posts=PATH_TO_POSTS, reverse=True):
    """
    Returns all of the posts in the directory and all directories below it.
    
    >>> posts, pages = get_documents('mango/examples')
    >>> posts[1].html
    u"\\n<p>Welcome to Mango. ... <strong>Congratulations!</strong></p>"
    """
    posts_cache_key = u'posts:%s' % path_to_posts
    pages_cache_key = u'pages:%s' % path_to_posts

    posts = cache.get(posts_cache_key)
    pages = cache.get(pages_cache_key)

    if posts is None or pages is None:
        documents = []
        for dirpath, dirnames, filenames in os.walk(path_to_posts):
            filenames[:] = [f for f in filenames if not f.startswith('.')]
            for filename in filenames:
                joined_path = os.path.join(dirpath, filename)
                absolute_path = os.path.abspath(joined_path)
                # ignore symlink if it points to a document in same directory
                if absolute_path == os.path.realpath(joined_path):
                    documents.append(get_document(absolute_path))

        posts, pages = [], []
        for document in documents:
            if document.type == 'page':
                pages.append(document)
            else:
                posts.append(document)

        posts.sort(key=lambda post: post.datetime, reverse=reverse)
        pages.sort(key=lambda page: page.title)

        cache.set(posts_cache_key, posts, INDEX_CACHE_SECONDS)
        cache.set(pages_cache_key, pages, INDEX_CACHE_SECONDS)

        if settings.DEBUG:
            num_posts, num_pages = len(posts), len(pages)
            print '%s Document object%s created and cached: %s' % (
                    num_posts, '' if num_posts is 1 else 's', posts_cache_key)
            print '%s Document object%s created and cached: %s' % (
                    num_pages, '' if num_pages is 1 else 's', pages_cache_key)

    elif settings.DEBUG:
        num_posts, num_pages = len(posts), len(pages)
        print '%s Document object%s retrieved from cache: %s' % (
                num_posts, '' if num_posts is 1 else 's', posts_cache_key)
        print '%s Document object%s retrieved from cache: %s' % (
                num_pages, '' if num_pages is 1 else 's', pages_cache_key)

    return posts, pages

def archives(path_to_posts=PATH_TO_POSTS):
    """
    Returns all of the posts in the directory and all directories below it,
    in the form (year, month, [posts]).
    
    >>> year, month, these_posts = archives('mango/examples')[1]
    >>> year == 2010
    True
    >>> month == 4
    True
    >>> these_posts[0].html
    u"\\n<p>Welcome to Mango. ... <strong>Congratulations!</strong></p>"
    """
    archives = []
    posts, pages = get_documents(path_to_posts)
    if posts:
        year = posts[0].datetime.year
        month = posts[0].datetime.month

        these_posts = []
        for post in posts:
            if post.datetime.year == year and post.datetime.month == month:
                these_posts.append(post)
            else:
                archives.append((year, month, these_posts))
                year, month = post.datetime.year, post.datetime.month
                these_posts = [post]
        archives.append((year, month, these_posts))

    return archives

def primary_author_email():
    """
    Returns the primary author's e-mail address as specified in Mango's
    settings file.
    
    >>> primary_author_email()
    u'... <...@...>'
    """
    name = PRIMARY_AUTHOR_NAME
    email = PRIMARY_AUTHOR_EMAIL
    if name and email:
        email = '%s <%s>' % (name, email)
    return email