1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
# -*- coding: utf-8 -*-
"""
simplewiki.utils
~~~~~~~~~~~~~~~~
This module implements various utility functions and classes used all
over the application.
:copyright: (c) 2009 by the Werkzeug Team, see AUTHORS for more details.
:license: BSD.
"""
import difflib
import creoleparser
from os import path
from genshi import Stream
from genshi.template import TemplateLoader
from werkzeug.local import Local, LocalManager
from werkzeug.urls import url_encode, url_quote
from werkzeug.utils import cached_property, redirect
from werkzeug.wrappers import BaseRequest, BaseResponse
# calculate the path to the templates an create the template loader
TEMPLATE_PATH = path.join(path.dirname(__file__), 'templates')
template_loader = TemplateLoader(TEMPLATE_PATH, auto_reload=True,
variable_lookup='lenient')
# context locals. these two objects are use by the application to
# bind objects to the current context. A context is defined as the
# current thread and the current greenlet if there is greenlet support.
local = Local()
local_manager = LocalManager([local])
request = local('request')
application = local('application')
# create a new creole parser
creole_parser = creoleparser.Parser(
dialect=creoleparser.create_dialect(creoleparser.creole10_base,
wiki_links_base_url='',
wiki_links_path_func=lambda page_name: href(page_name),
wiki_links_space_char='_',
no_wiki_monospace=True
),
method='html'
)
def generate_template(template_name, **context):
"""Load and generate a template."""
context.update(
href=href,
format_datetime=format_datetime
)
return template_loader.load(template_name).generate(**context)
def parse_creole(markup):
"""Parse some creole markup and create a genshi stream."""
return creole_parser.generate(markup)
def href(*args, **kw):
"""
Simple function for URL generation. Position arguments are used for the
URL path and keyword arguments are used for the url parameters.
"""
result = [(request and request.script_root or '') + '/']
for idx, arg in enumerate(args):
result.append((idx and '/' or '') + url_quote(arg))
if kw:
result.append('?' + url_encode(kw))
return ''.join(result)
def format_datetime(obj):
"""Format a datetime object."""
return obj.strftime('%Y-%m-%d %H:%M')
class Request(BaseRequest):
"""
Simple request subclass that allows to bind the object to the
current context.
"""
def bind_to_context(self):
local.request = self
class Response(BaseResponse):
"""
Encapsulates a WSGI response. Unlike the default response object werkzeug
provides, this accepts a genshi stream and will automatically render it
to html. This makes it possible to switch to xhtml or html5 easily.
"""
default_mimetype = 'text/html'
def __init__(self, response=None, status=200, headers=None, mimetype=None,
content_type=None):
if isinstance(response, Stream):
response = response.render('html', encoding=None, doctype='html')
BaseResponse.__init__(self, response, status, headers, mimetype,
content_type)
class Pagination(object):
"""
Paginate a SQLAlchemy query object.
"""
def __init__(self, query, per_page, page, link):
self.query = query
self.per_page = per_page
self.page = page
self.link = link
self._count = None
@cached_property
def entries(self):
return self.query.offset((self.page - 1) * self.per_page) \
.limit(self.per_page).all()
@property
def has_previous(self):
return self.page > 1
@property
def has_next(self):
return self.page < self.pages
@property
def previous(self):
return href(self.link, page=self.page - 1)
@property
def next(self):
return href(self.link, page=self.page + 1)
@cached_property
def count(self):
return self.query.count()
@property
def pages(self):
return max(0, self.count - 1) // self.per_page + 1
|