2009-01-05 14:30:08 +02:00
from datetime import datetime
import os . path
import random
2009-01-17 14:42:12 +02:00
import re
2009-01-09 16:11:30 +02:00
from HTMLParser import HTMLParser
2009-01-05 14:30:08 +02:00
from django . shortcuts import render_to_response
from django . template import RequestContext
2009-08-24 23:37:53 +03:00
from django . http import HttpResponse , Http404
2009-01-05 14:30:08 +02:00
from django . utils . functional import Promise
2009-03-03 18:30:41 +02:00
from django . utils . translation import force_unicode , check_for_language
2009-01-05 14:30:08 +02:00
from django . utils . simplejson import JSONEncoder
from django import forms
from django . template . defaultfilters import urlize as django_urlize
2009-08-24 23:37:53 +03:00
from django . core . paginator import Paginator , EmptyPage , InvalidPage
2010-02-17 14:03:30 +02:00
from django . contrib . sites . models import Site
2009-03-03 18:30:41 +02:00
from django . conf import settings
2009-01-05 14:30:08 +02:00
2009-12-23 17:06:48 +02:00
from djangobb_forum import settings as forum_settings
2009-01-05 14:30:08 +02:00
2009-03-03 18:30:41 +02:00
2009-01-21 18:28:36 +02:00
#compile smiles regexp
_SMILES = [ ( re . compile ( smile_re ) , path ) for smile_re , path in forum_settings . SMILES ]
2010-01-04 14:17:36 +02:00
2009-01-21 01:13:46 +02:00
def render_to ( template ) :
2009-01-05 14:30:08 +02:00
"""
2009-08-20 12:46:08 +03:00
Decorator for Django views that sends returned dict to render_to_response function .
2009-01-05 14:30:08 +02:00
2009-08-20 12:46:08 +03:00
Template name can be decorator parameter or TEMPLATE item in returned dictionary .
RequestContext always added as context instance .
2009-01-21 01:13:46 +02:00
If view doesn ' t return dict then decorator simply returns output.
Parameters :
- template : template name to use
2009-08-20 12:46:08 +03:00
Examples :
# 1. Template name in decorator parameters
@render_to ( ' template.html ' )
def foo ( request ) :
bar = Bar . object . all ( )
return { ' bar ' : bar }
2009-01-21 01:13:46 +02:00
2009-08-20 12:46:08 +03:00
# equals to
def foo ( request ) :
bar = Bar . object . all ( )
return render_to_response ( ' template.html ' ,
{ ' bar ' : bar } ,
context_instance = RequestContext ( request ) )
2009-01-21 01:13:46 +02:00
2009-08-20 12:46:08 +03:00
# 2. Template name as TEMPLATE item value in return dictionary
@render_to ( )
def foo ( request , category ) :
template_name = ' %s .html ' % category
return { ' bar ' : bar , ' TEMPLATE ' : template_name }
#equals to
def foo ( request , category ) :
template_name = ' %s .html ' % category
return render_to_response ( template_name ,
{ ' bar ' : bar } ,
context_instance = RequestContext ( request ) )
2009-01-21 01:13:46 +02:00
"""
2009-08-20 12:46:08 +03:00
def renderer ( function ) :
def wrapper ( request , * args , * * kwargs ) :
output = function ( request , * args , * * kwargs )
if not isinstance ( output , dict ) :
return output
tmpl = output . pop ( ' TEMPLATE ' , template )
return render_to_response ( tmpl , output , context_instance = RequestContext ( request ) )
2009-01-21 01:13:46 +02:00
return wrapper
return renderer
2009-01-05 14:30:08 +02:00
2010-01-04 14:17:36 +02:00
2009-01-19 19:50:01 +02:00
def absolute_url ( path ) :
2010-02-17 14:03:30 +02:00
return ' http:// %s %s ' % ( Site . objects . get_current ( ) . domain , path )
2009-01-05 14:30:08 +02:00
2010-01-04 14:17:36 +02:00
2009-08-20 12:46:08 +03:00
def paged ( paged_list_name , per_page ) :
2009-01-05 14:30:08 +02:00
"""
Parse page from GET data and pass it to view . Split the
query set returned from view .
"""
2009-08-20 12:46:08 +03:00
2009-01-05 14:30:08 +02:00
def decorator ( func ) :
def wrapper ( request , * args , * * kwargs ) :
result = func ( request , * args , * * kwargs )
2009-08-20 12:46:08 +03:00
if not isinstance ( result , dict ) or ' paged_qs ' not in result :
2009-01-05 14:30:08 +02:00
return result
try :
page = int ( request . GET . get ( ' page ' , 1 ) )
except ValueError :
page = 1
real_per_page = per_page
#if per_page_var:
#try:
#value = int(request.GET[per_page_var])
#except (ValueError, KeyError):
#pass
#else:
#if value > 0:
#real_per_page = value
from django . core . paginator import Paginator
paginator = Paginator ( result [ ' paged_qs ' ] , real_per_page )
2009-08-27 17:41:42 +03:00
try :
result [ paged_list_name ] = paginator . page ( page ) . object_list
except ( InvalidPage , EmptyPage ) :
raise Http404
2009-01-05 14:30:08 +02:00
result [ ' page ' ] = page
result [ ' page_list ' ] = range ( 1 , paginator . num_pages + 1 )
result [ ' pages ' ] = paginator . num_pages
result [ ' per_page ' ] = real_per_page
result [ ' request ' ] = request
return result
return wrapper
return decorator
def ajax ( func ) :
"""
Checks request . method is POST . Return error in JSON in other case .
If view returned dict , returns JsonResponse with this dict as content .
"""
def wrapper ( request , * args , * * kwargs ) :
if request . method == ' POST ' :
try :
response = func ( request , * args , * * kwargs )
except Exception , ex :
response = { ' error ' : traceback . format_exc ( ) }
else :
response = { ' error ' : { ' type ' : 403 , ' message ' : ' Accepts only POST request ' } }
if isinstance ( response , dict ) :
return JsonResponse ( response )
else :
return response
return wrapper
class LazyJSONEncoder ( JSONEncoder ) :
"""
This fing need to save django from crashing .
"""
def default ( self , o ) :
if isinstance ( o , Promise ) :
return force_unicode ( o )
else :
return super ( LazyJSONEncoder , self ) . default ( o )
class JsonResponse ( HttpResponse ) :
"""
HttpResponse subclass that serialize data into JSON format .
"""
def __init__ ( self , data , mimetype = ' application/json ' ) :
json_data = LazyJSONEncoder ( ) . encode ( data )
super ( JsonResponse , self ) . __init__ (
content = json_data , mimetype = mimetype )
2010-01-05 15:56:19 +02:00
2009-01-05 14:30:08 +02:00
def build_form ( Form , _request , GET = False , * args , * * kwargs ) :
"""
2009-07-02 16:01:22 +03:00
Shorcut for building the form instance of given form class
2009-01-05 14:30:08 +02:00
"""
if not GET and ' POST ' == _request . method :
form = Form ( _request . POST , _request . FILES , * args , * * kwargs )
elif GET and ' GET ' == _request . method :
form = Form ( _request . GET , _request . FILES , * args , * * kwargs )
else :
form = Form ( * args , * * kwargs )
return form
2010-01-05 15:56:19 +02:00
2009-01-21 18:28:36 +02:00
class ExcludeTagsHTMLParser ( HTMLParser ) :
"""
Class for html parsing with excluding specified tags .
"""
def __init__ ( self , func , tags = ( ' a ' , ' code ' ) ) :
2009-01-09 16:11:30 +02:00
HTMLParser . __init__ ( self )
2009-01-21 18:28:36 +02:00
self . func = func
self . is_ignored = False
self . tags = tags
self . html = [ ]
2009-01-09 16:11:30 +02:00
def handle_starttag ( self , tag , attrs ) :
2009-01-21 18:28:36 +02:00
self . html . append ( ' < %s %s > ' % ( tag , self . __html_attrs ( attrs ) ) )
if tag in self . tags :
self . is_ignored = True
2009-01-09 16:11:30 +02:00
def handle_data ( self , data ) :
2009-01-21 18:28:36 +02:00
if not self . is_ignored :
data = self . func ( data )
self . html . append ( data )
2009-01-09 16:11:30 +02:00
def handle_startendtag ( self , tag , attrs ) :
2009-01-21 18:28:36 +02:00
self . html . append ( ' < %s %s /> ' % ( tag , self . __html_attrs ( attrs ) ) )
2009-01-09 16:11:30 +02:00
def handle_endtag ( self , tag ) :
2009-01-21 18:28:36 +02:00
self . is_ignored = False
self . html . append ( ' </ %s > ' % ( tag ) )
2009-01-20 17:42:02 +02:00
def handle_entityref ( self , name ) :
2009-01-21 18:28:36 +02:00
self . html . append ( ' & %s ; ' % name )
2009-01-20 17:42:02 +02:00
def handle_charref ( self , name ) :
2010-01-04 14:17:36 +02:00
self . html . append ( ' &# %s ; ' % name )
2009-01-20 17:42:02 +02:00
2010-01-05 15:56:19 +02:00
def unescape ( self , s ) :
#we don't need unescape data (without this possible XSS-attack)
return s
2009-01-09 16:11:30 +02:00
def __html_attrs ( self , attrs ) :
_attrs = ' '
if attrs :
_attrs = ' %s ' % ( ' ' . join ( [ ( ' %s = " %s " ' % ( k , v ) ) for k , v in attrs ] ) )
return _attrs
2009-01-21 18:28:36 +02:00
2009-01-09 16:11:30 +02:00
def feed ( self , data ) :
HTMLParser . feed ( self , data )
2009-01-21 18:28:36 +02:00
self . html = ' ' . join ( self . html )
2010-01-05 15:56:19 +02:00
2009-01-21 18:28:36 +02:00
def urlize ( data ) :
"""
Urlize plain text links in the HTML contents .
Do not urlize content of A and CODE tags .
"""
parser = ExcludeTagsHTMLParser ( django_urlize )
2009-01-09 16:11:30 +02:00
parser . feed ( data )
2009-01-21 18:28:36 +02:00
urlized_html = parser . html
2009-01-09 16:11:30 +02:00
parser . close ( )
return urlized_html
2009-01-05 14:30:08 +02:00
2009-01-21 18:28:36 +02:00
def _smile_replacer ( data ) :
for smile , path in _SMILES :
data = smile . sub ( path , data )
2009-01-17 14:42:12 +02:00
return data
2009-01-21 18:28:36 +02:00
def smiles ( data ) :
"""
Replace text smiles .
"""
parser = ExcludeTagsHTMLParser ( _smile_replacer )
parser . feed ( data )
smiled_html = parser . html
parser . close ( )
return smiled_html
2009-02-09 20:31:19 +02:00
def paginate ( items , request , per_page , total_count = None ) :
try :
page_number = int ( request . GET . get ( ' page ' , 1 ) )
except ValueError :
page_number = 1
2009-10-19 14:02:27 +03:00
2009-02-09 20:31:19 +02:00
paginator = Paginator ( items , per_page )
pages = paginator . num_pages
2009-08-24 23:37:53 +03:00
try :
paged_list_name = paginator . page ( page_number ) . object_list
except ( InvalidPage , EmptyPage ) :
2010-01-04 14:17:36 +02:00
raise Http404
2009-02-09 20:31:19 +02:00
return pages , paginator , paged_list_name
def set_language ( request , language ) :
"""
Change the language of session of authenticated user .
"""
if language and check_for_language ( language ) :
if hasattr ( request , ' session ' ) :
request . session [ ' django_language ' ] = language
else :
response . set_cookie ( settings . LANGUAGE_COOKIE_NAME , language )