source: djangobb/djangobb_forum/util.py @ 211:fd81e8a20369

Last change on this file since 211:fd81e8a20369 was 211:fd81e8a20369, checked in by slav0nic <slav0nic0@…>, 3 years ago

main app moved from apps/forum to djangobb_forum. Warning: you must renaming DB tables prefix!

File size: 8.3 KB
Line 
1from datetime import datetime
2import os.path
3import random
4import re
5from HTMLParser import HTMLParser
6
7from django.shortcuts import render_to_response
8from django.template import RequestContext
9from django.http import HttpResponse, Http404
10from django.utils.functional import Promise
11from django.utils.translation import force_unicode, check_for_language
12from django.utils.simplejson import JSONEncoder
13from django import forms
14from django.template.defaultfilters import urlize as django_urlize
15from django.core.paginator import Paginator, EmptyPage, InvalidPage
16from django.conf import settings
17
18from djangobb_forum import settings as forum_settings
19
20
21#compile smiles regexp
22_SMILES = [(re.compile(smile_re), path) for smile_re, path in forum_settings.SMILES]
23
24def render_to(template):
25    """
26    Decorator for Django views that sends returned dict to render_to_response function.
27
28    Template name can be decorator parameter or TEMPLATE item in returned dictionary.
29    RequestContext always added as context instance.
30    If view doesn't return dict then decorator simply returns output.
31
32    Parameters:
33     - template: template name to use
34
35    Examples:
36    # 1. Template name in decorator parameters
37
38    @render_to('template.html')
39    def foo(request):
40        bar = Bar.object.all() 
41        return {'bar': bar}
42
43    # equals to
44    def foo(request):
45        bar = Bar.object.all() 
46        return render_to_response('template.html',
47                                  {'bar': bar},
48                                  context_instance=RequestContext(request))
49
50    # 2. Template name as TEMPLATE item value in return dictionary
51
52    @render_to()
53    def foo(request, category):
54        template_name = '%s.html' % category
55        return {'bar': bar, 'TEMPLATE': template_name}
56   
57    #equals to
58    def foo(request, category):
59        template_name = '%s.html' % category
60        return render_to_response(template_name,
61                                  {'bar': bar},
62                                  context_instance=RequestContext(request))
63    """
64
65    def renderer(function):
66        def wrapper(request, *args, **kwargs):
67            output = function(request, *args, **kwargs)
68            if not isinstance(output, dict):
69                return output
70            tmpl = output.pop('TEMPLATE', template)
71            return render_to_response(tmpl, output, context_instance=RequestContext(request))
72        return wrapper
73    return renderer
74
75def absolute_url(path):
76    return 'http://%s%s' % (forum_settings.HOST, path)
77
78def paged(paged_list_name, per_page):
79    """
80    Parse page from GET data and pass it to view. Split the
81    query set returned from view.
82    """
83
84    def decorator(func):
85        def wrapper(request, *args, **kwargs):
86            result = func(request, *args, **kwargs)
87            if not isinstance(result, dict) or 'paged_qs' not in result:
88                return result
89            try:
90                page = int(request.GET.get('page', 1))
91            except ValueError:
92                page = 1
93
94            real_per_page = per_page
95
96            #if per_page_var:
97                #try:
98                    #value = int(request.GET[per_page_var])
99                #except (ValueError, KeyError):
100                    #pass
101                #else:
102                    #if value > 0:
103                        #real_per_page = value
104
105            from django.core.paginator import Paginator
106            paginator = Paginator(result['paged_qs'], real_per_page)
107            try:
108                result[paged_list_name] = paginator.page(page).object_list
109            except (InvalidPage, EmptyPage):
110                raise Http404
111            result['page'] = page
112            result['page_list'] = range(1, paginator.num_pages + 1)
113            result['pages'] = paginator.num_pages
114            result['per_page'] = real_per_page
115            result['request'] = request
116            return result
117        return wrapper
118
119    return decorator
120
121
122def ajax(func):
123    """
124    Checks request.method is POST. Return error in JSON in other case.
125
126    If view returned dict, returns JsonResponse with this dict as content.
127    """
128    def wrapper(request, *args, **kwargs):
129        if request.method == 'POST':
130            try:
131                response = func(request, *args, **kwargs)
132            except Exception, ex:
133                response = {'error': traceback.format_exc()}
134        else:
135            response = {'error': {'type': 403, 'message': 'Accepts only POST request'}}
136        if isinstance(response, dict):
137            return JsonResponse(response)
138        else:
139            return response
140    return wrapper
141
142
143class LazyJSONEncoder(JSONEncoder):
144    """
145    This fing need to save django from crashing.
146    """
147
148    def default(self, o):
149        if isinstance(o, Promise):
150            return force_unicode(o)
151        else:
152            return super(LazyJSONEncoder, self).default(o)
153
154
155class JsonResponse(HttpResponse):
156    """
157    HttpResponse subclass that serialize data into JSON format.
158    """
159
160    def __init__(self, data, mimetype='application/json'):
161        json_data = LazyJSONEncoder().encode(data)
162        super(JsonResponse, self).__init__(
163            content=json_data, mimetype=mimetype)
164
165       
166def build_form(Form, _request, GET=False, *args, **kwargs):
167    """
168    Shorcut for building the form instance of given form class
169    """
170
171    if not GET and 'POST' == _request.method:
172        form = Form(_request.POST, _request.FILES, *args, **kwargs)
173    elif GET and 'GET' == _request.method:
174        form = Form(_request.GET, _request.FILES, *args, **kwargs)
175    else:
176        form = Form(*args, **kwargs)
177    return form
178
179class ExcludeTagsHTMLParser(HTMLParser):
180        """
181        Class for html parsing with excluding specified tags.
182        """
183
184        def __init__(self, func, tags=('a', 'code')):
185            HTMLParser.__init__(self)
186            self.func = func
187            self.is_ignored = False
188            self.tags = tags
189            self.html = []
190
191        def handle_starttag(self, tag, attrs):
192            self.html.append('<%s%s>' % (tag, self.__html_attrs(attrs)))
193            if tag in self.tags:
194                self.is_ignored = True
195
196        def handle_data(self, data):
197            if not self.is_ignored:
198                data = self.func(data)
199            self.html.append(data)
200
201        def handle_startendtag(self, tag, attrs):
202            self.html.append('<%s%s/>' % (tag, self.__html_attrs(attrs))) 
203
204        def handle_endtag(self, tag):
205            self.is_ignored = False
206            self.html.append('</%s>' % (tag))
207
208        def handle_entityref(self, name):
209            self.html.append('&%s;' % name)
210
211        def handle_charref(self, name):
212            self.html.append('&%s;' % name)
213
214        def __html_attrs(self, attrs):
215            _attrs = ''
216            if attrs:
217                _attrs = ' %s' % (' '.join([('%s="%s"' % (k,v)) for k,v in attrs]))
218            return _attrs
219
220        def feed(self, data):
221            HTMLParser.feed(self, data)
222            self.html = ''.join(self.html)
223
224def urlize(data):
225    """
226    Urlize plain text links in the HTML contents.
227   
228    Do not urlize content of A and CODE tags.
229    """
230
231    parser = ExcludeTagsHTMLParser(django_urlize)
232    parser.feed(data)
233    urlized_html = parser.html
234    parser.close()
235    return urlized_html
236
237def _smile_replacer(data):
238    for smile, path in _SMILES:
239        data = smile.sub(path, data)
240    return data
241
242def smiles(data):
243    """
244    Replace text smiles.
245    """
246
247    parser = ExcludeTagsHTMLParser(_smile_replacer)
248    parser.feed(data)
249    smiled_html = parser.html
250    parser.close()
251    return smiled_html
252
253def paginate(items, request, per_page, total_count=None):
254    try:
255        page_number = int(request.GET.get('page', 1))
256    except ValueError:
257        page_number = 1
258
259    paginator = Paginator(items, per_page)
260    pages = paginator.num_pages
261    try:
262        paged_list_name = paginator.page(page_number).object_list
263    except (InvalidPage, EmptyPage):
264       raise Http404
265    return pages, paginator, paged_list_name
266
267def set_language(request, language):
268    """
269    Change the language of session of authenticated user.
270    """
271
272    if language and check_for_language(language):
273        if hasattr(request, 'session'):
274            request.session['django_language'] = language
275        else:
276            response.set_cookie(settings.LANGUAGE_COOKIE_NAME, language) 
Note: See TracBrowser for help on using the repository browser.