~widelands-dev/widelands-website/django_staticfiles

« back to all changes in this revision

Viewing changes to pybb/util.py

  • Committer: Holger Rapp
  • Date: 2009-02-25 16:55:36 UTC
  • Revision ID: sirver@kallisto.local-20090225165536-3abfhjx8qsgtzyru
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from datetime import datetime
 
2
import os.path
 
3
import random
 
4
from BeautifulSoup import BeautifulSoup
 
5
import traceback
 
6
 
 
7
from django.shortcuts import render_to_response
 
8
from django.template import RequestContext
 
9
from django.http import HttpResponse
 
10
from django.utils.functional import Promise
 
11
from django.utils.translation import force_unicode, check_for_language
 
12
from django.utils.simplejson import JSONEncoder
 
13
from django import forms
 
14
from django.template.defaultfilters import urlize as django_urlize
 
15
from django.core.paginator import Paginator, EmptyPage, InvalidPage
 
16
from django.conf import settings
 
17
 
 
18
from pybb import settings as pybb_settings
 
19
 
 
20
 
 
21
def render_to(template_path):
 
22
    """
 
23
    Expect the dict from view. Render returned dict with
 
24
    RequestContext.
 
25
    """
 
26
 
 
27
    def decorator(func):
 
28
        def wrapper(request, *args, **kwargs):
 
29
            import pdb
 
30
            #output = pdb.runcall(func, request, *args, **kwargs)
 
31
            output = func(request, *args, **kwargs)
 
32
            if not isinstance(output, dict):
 
33
                return output
 
34
            kwargs = {'context_instance': RequestContext(request)}
 
35
            if 'MIME_TYPE' in output:
 
36
                kwargs['mimetype'] = output.pop('MIME_TYPE')
 
37
            if 'TEMPLATE' in output:
 
38
                template = output.pop('TEMPLATE')
 
39
            else:
 
40
                template = template_path
 
41
            return render_to_response(template, output, **kwargs)
 
42
        return wrapper
 
43
 
 
44
    return decorator
 
45
 
 
46
 
 
47
def paged(paged_list_name, per_page):#, per_page_var='per_page'):
 
48
    """
 
49
    Parse page from GET data and pass it to view. Split the
 
50
    query set returned from view.
 
51
    """
 
52
    
 
53
    def decorator(func):
 
54
        def wrapper(request, *args, **kwargs):
 
55
            result = func(request, *args, **kwargs)
 
56
            if not isinstance(result, dict):
 
57
                return result
 
58
            try:
 
59
                page = int(request.GET.get('page', 1))
 
60
            except ValueError:
 
61
                page = 1
 
62
 
 
63
            real_per_page = per_page
 
64
 
 
65
            #if per_page_var:
 
66
                #try:
 
67
                    #value = int(request.GET[per_page_var])
 
68
                #except (ValueError, KeyError):
 
69
                    #pass
 
70
                #else:
 
71
                    #if value > 0:
 
72
                        #real_per_page = value
 
73
 
 
74
            from django.core.paginator import Paginator
 
75
            paginator = Paginator(result['paged_qs'], real_per_page)
 
76
            result[paged_list_name] = paginator.page(page).object_list
 
77
            result['page'] = page
 
78
            result['page_list'] = range(1, paginator.num_pages + 1)
 
79
            result['pages'] = paginator.num_pages
 
80
            result['per_page'] = real_per_page
 
81
            result['request'] = request
 
82
            return result
 
83
        return wrapper
 
84
 
 
85
    return decorator
 
86
 
 
87
 
 
88
def ajax(func):
 
89
    """
 
90
    Checks request.method is POST. Return error in JSON in other case.
 
91
 
 
92
    If view returned dict, returns JsonResponse with this dict as content.
 
93
    """
 
94
    def wrapper(request, *args, **kwargs):
 
95
        if request.method == 'POST':
 
96
            try:
 
97
                response = func(request, *args, **kwargs)
 
98
            except Exception, ex:
 
99
                response = {'error': traceback.format_exc()}
 
100
        else:
 
101
            response = {'error': {'type': 403, 'message': 'Accepts only POST request'}}
 
102
        if isinstance(response, dict):
 
103
            return JsonResponse(response)
 
104
        else:
 
105
            return response
 
106
    return wrapper
 
107
 
 
108
 
 
109
class LazyJSONEncoder(JSONEncoder):
 
110
    """
 
111
    This fing need to save django from crashing.
 
112
    """
 
113
 
 
114
    def default(self, o):
 
115
        if isinstance(o, Promise):
 
116
            return force_unicode(o)
 
117
        else:
 
118
            return super(LazyJSONEncoder, self).default(o)
 
119
 
 
120
 
 
121
class JsonResponse(HttpResponse):
 
122
    """
 
123
    HttpResponse subclass that serialize data into JSON format.
 
124
    """
 
125
 
 
126
    def __init__(self, data, mimetype='application/json'):
 
127
        json_data = LazyJSONEncoder().encode(data)
 
128
        super(JsonResponse, self).__init__(
 
129
            content=json_data, mimetype=mimetype)
 
130
 
 
131
        
 
132
def build_form(Form, _request, GET=False, *args, **kwargs):
 
133
    """
 
134
    Shorcut for building the form instance of given form class.
 
135
    """
 
136
 
 
137
    if not GET and 'POST' == _request.method:
 
138
        form = Form(_request.POST, _request.FILES, *args, **kwargs)
 
139
    elif GET and 'GET' == _request.method:
 
140
        form = Form(_request.GET, _request.FILES, *args, **kwargs)
 
141
    else:
 
142
        form = Form(*args, **kwargs)
 
143
    return form
 
144
    
 
145
 
 
146
def urlize(data):
 
147
        """
 
148
        Urlize plain text links in the HTML contents.
 
149
       
 
150
        Do not urlize content of A and CODE tags.
 
151
        """
 
152
 
 
153
        soup = BeautifulSoup(data)
 
154
        for chunk in soup.findAll(text=True):
 
155
            islink = False
 
156
            ptr = chunk.parent
 
157
            while ptr.parent:
 
158
                if ptr.name == 'a' or ptr.name == 'code':
 
159
                    islink = True
 
160
                    break
 
161
                ptr = ptr.parent
 
162
 
 
163
            if not islink:
 
164
                chunk = chunk.replaceWith(django_urlize(unicode(chunk)))
 
165
 
 
166
        return unicode(soup)
 
167
 
 
168
 
 
169
def quote_text(text, user, markup):
 
170
    """
 
171
    Quote message using selected markup.
 
172
    """
 
173
    text = user.username + " wrote:\n" + text
 
174
 
 
175
    if markup == 'markdown':
 
176
        return '>'+text.replace('\n','\n>').replace('\r','\n>') + '\n'
 
177
    elif markup == 'bbcode':
 
178
        return '[quote]\n%s\n[/quote]\n' % text
 
179
    else:
 
180
        return text
 
181
 
 
182
 
 
183
def absolute_url(path):
 
184
    return 'http://%s%s' % (pybb_settings.HOST, path)
 
185
 
 
186
 
 
187
def memoize_method(func):
 
188
    """
 
189
    Cached result of function call.
 
190
    """
 
191
 
 
192
    def wrapper(self, *args, **kwargs):
 
193
        CACHE_NAME = '__memcache'
 
194
        try:
 
195
            cache = getattr(self, CACHE_NAME)
 
196
        except AttributeError:
 
197
            cache = {}
 
198
            setattr(self, CACHE_NAME, cache)
 
199
        key = (func, tuple(args), frozenset(kwargs.items()))
 
200
        if key not in cache:
 
201
            cache[key] = func(self, *args, **kwargs)
 
202
        return cache[key]
 
203
    return wrapper
 
204
 
 
205
 
 
206
def paginate(items, request, per_page, total_count=None):
 
207
    try:
 
208
        page_number = int(request.GET.get('page', 1))
 
209
    except ValueError:
 
210
        page_number = 1
 
211
 
 
212
    paginator = Paginator(items, per_page)
 
213
    if total_count:
 
214
        paginator._count = total_count
 
215
 
 
216
    try:
 
217
        page = paginator.page(page_number)
 
218
    except (EmptyPage, InvalidPage):
 
219
        page = paginator.page(1)
 
220
 
 
221
    if page.has_previous:
 
222
        get = request.GET.copy()
 
223
        get['page'] = page.number - 1
 
224
        page.previous_link = '?%s' % get.urlencode()
 
225
    else:
 
226
        page.previous_link = None
 
227
 
 
228
    if page.has_next:
 
229
        get = request.GET.copy()
 
230
        get['page'] = page.number + 1
 
231
        page.next_link = '?%s' % get.urlencode()
 
232
    else:
 
233
        page.next_link = None
 
234
 
 
235
    #import pdb; pdb.set_trace()
 
236
    
 
237
    return page, paginator
 
238
 
 
239
 
 
240
def set_language(request, language):
 
241
    """
 
242
    Change the language of session of authenticated user.
 
243
    """
 
244
 
 
245
    if language and check_for_language(language):
 
246
        if hasattr(request, 'session'):
 
247
            request.session['django_language'] = language
 
248
        else:
 
249
            response.set_cookie(settings.LANGUAGE_COOKIE_NAME, language)
 
250
 
 
251
 
 
252
def unescape(text):
 
253
    """
 
254
    Do reverse escaping.
 
255
    """
 
256
 
 
257
    text = text.replace('&', '&')
 
258
    text = text.replace('&lt;', '<')
 
259
    text = text.replace('&gt;', '>')
 
260
    text = text.replace('&quot;', '"')
 
261
    text = text.replace('&#39;', '\'')
 
262
    return text