~widelands-dev/widelands-website/trunk

22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
1
import os.path
2
import random
404.2.1 by franku
first try on Django1.8
3
import traceback
4
import json
504.3.4 by franku
fixing urlizing of plain links
5
import re
404.2.1 by franku
first try on Django1.8
6
504.3.4 by franku
fixing urlizing of plain links
7
from bs4 import BeautifulSoup, NavigableString
404.2.1 by franku
first try on Django1.8
8
from datetime import datetime
489.1.1 by franku
url fixes; render_to_response() -> render(); disabled tracking
9
from django.shortcuts import render
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
10
from django.http import HttpResponse
11
from django.utils.functional import Promise
404.2.1 by franku
first try on Django1.8
12
from django.utils.translation import check_for_language
13
from django.utils.encoding import force_unicode
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
14
from django import forms
15
from django.core.paginator import Paginator, EmptyPage, InvalidPage
16
from django.conf import settings
17
from pybb import settings as pybb_settings
18
19
20
def render_to(template_path):
438.1.6 by franku
run the script
21
    """Expect the dict from view.
22
23
    Render returned dict with RequestContext.
24
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
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
489.1.1 by franku
url fixes; render_to_response() -> render(); disabled tracking
34
            
438.1.6 by franku
run the script
35
447.1.5 by franku
addressed code review; fixed errors shown by w3c
36
            # TODO(Franku): 'MIME_TYPE' is never in output as i can see for now.
404.2.12 by franku
runthrough deprecation timeline; fixed some things; added NOCOMMs
37
            # But if, this should maybe 'content_type' instead
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
38
            if 'MIME_TYPE' in output:
39
                kwargs['mimetype'] = output.pop('MIME_TYPE')
40
            if 'TEMPLATE' in output:
41
                template = output.pop('TEMPLATE')
42
            else:
43
                template = template_path
438.1.6 by franku
run the script
44
489.1.1 by franku
url fixes; render_to_response() -> render(); disabled tracking
45
            return render(request, template, output)
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
46
        return wrapper
47
48
    return decorator
49
50
51
def ajax(func):
438.1.6 by franku
run the script
52
    """Checks request.method is POST. Return error in JSON in other case.
53
54
    If view returned dict, returns JsonResponse with this dict as
55
    content.
56
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
57
    """
58
    def wrapper(request, *args, **kwargs):
59
        if request.method == 'POST':
60
            try:
61
                response = func(request, *args, **kwargs)
62
            except Exception, ex:
63
                response = {'error': traceback.format_exc()}
64
        else:
438.1.6 by franku
run the script
65
            response = {'error': {'type': 403,
66
                                  'message': 'Accepts only POST request'}}
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
67
        if isinstance(response, dict):
68
            return JsonResponse(response)
69
        else:
70
            return response
71
    return wrapper
72
73
404.2.1 by franku
first try on Django1.8
74
class LazyJSONEncoder(json.JSONEncoder):
438.1.6 by franku
run the script
75
    """This fing need to save django from crashing."""
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
76
77
    def default(self, o):
78
        if isinstance(o, Promise):
79
            return force_unicode(o)
80
        else:
81
            return super(LazyJSONEncoder, self).default(o)
82
83
84
class JsonResponse(HttpResponse):
438.1.6 by franku
run the script
85
    """HttpResponse subclass that serialize data into JSON format."""
447.1.5 by franku
addressed code review; fixed errors shown by w3c
86
    # TODO(Franku): The mimetype argument maybe must be replaced with content_type
438.1.6 by franku
run the script
87
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
88
    def __init__(self, data, mimetype='application/json'):
89
        json_data = LazyJSONEncoder().encode(data)
90
        super(JsonResponse, self).__init__(
404.2.14 by franku
reactivated preview for forum
91
            content=json_data, content_type=mimetype)
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
92
438.1.6 by franku
run the script
93
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
94
def build_form(Form, _request, GET=False, *args, **kwargs):
438.1.6 by franku
run the script
95
    """Shorcut for building the form instance of given form class."""
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
96
97
    if not GET and 'POST' == _request.method:
98
        form = Form(_request.POST, _request.FILES, *args, **kwargs)
99
    elif GET and 'GET' == _request.method:
100
        form = Form(_request.GET, _request.FILES, *args, **kwargs)
101
    else:
102
        form = Form(*args, **kwargs)
103
    return form
438.1.6 by franku
run the script
104
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
105
504.3.15 by franku
slightly modified regex
106
PLAIN_LINK_RE = re.compile(r'(http[s]?:\/\/[-a-zA-Z0-9@:%._\+~#=/?]+)')
504.3.17 by franku
exclude external links in code tags
107
def exclude_code_tag(bs4_string):
108
    if bs4_string.parent.name == 'code':
109
        return False
110
    m = PLAIN_LINK_RE.search(bs4_string)
111
    if m:
112
        return True
113
    return False
114
504.3.4 by franku
fixing urlizing of plain links
115
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
116
def urlize(data):
438.1.6 by franku
run the script
117
    """Urlize plain text links in the HTML contents.
118
119
    Do not urlize content of A and CODE tags.
120
121
    """
122
504.3.4 by franku
fixing urlizing of plain links
123
    soup = BeautifulSoup(data, 'lxml')
504.3.17 by franku
exclude external links in code tags
124
    for found_string in soup.find_all(string=exclude_code_tag):
504.3.5 by franku
some cleanups; there is yet something wrong with smileys though
125
        new_content = []
504.3.7 by franku
working version for pybb
126
        strings_or_tags = found_string.parent.contents
127
        for string_or_tag in strings_or_tags:
128
            try:
504.3.9 by franku
cleanups
129
                for string in PLAIN_LINK_RE.split(string_or_tag):
504.3.7 by franku
working version for pybb
130
                    if string.startswith('http'):
504.3.8 by franku
commenting
131
                        # Apply an a-Tag
504.3.7 by franku
working version for pybb
132
                        tag = soup.new_tag('a')
133
                        tag['href'] = string
134
                        tag.string = string
135
                        tag['nofollow'] = 'true'
136
                        new_content.append(tag)
137
                    else:
504.3.8 by franku
commenting
138
                        # This is just a string, apply a bs4-string
504.3.7 by franku
working version for pybb
139
                        new_content.append(NavigableString(string))
140
            except:
504.3.9 by franku
cleanups
141
                # Regex failed, so apply what ever it is
504.3.7 by franku
working version for pybb
142
                new_content.append(string_or_tag)
504.3.11 by franku
use the regex directly
143
504.3.8 by franku
commenting
144
        # Apply the new content
504.3.7 by franku
working version for pybb
145
        found_string.parent.contents = new_content
438.1.6 by franku
run the script
146
147
    return unicode(soup)
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
148
149
150
def quote_text(text, user, markup):
438.1.6 by franku
run the script
151
    """Quote message using selected markup."""
497.3.4 by franku
fixed link; fixed showing deleted user when quoting a post
152
153
    quoted_username = settings.DELETED_USERNAME if user.wlprofile.deleted else user.username
154
155
    text = '*' + quoted_username + ' wrote:*\n\n' + text
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
156
209.1.68 by Timo Wingender
add field to choose between markdown and bbcode as markup
157
    if markup == 'markdown':
381.1.2 by frankusomal at arcor
smiley-and-codeblock-enhancements-corrected
158
        # Inserting a space after ">" will not change the generated HTML,
159
        # but it will unbreak certain constructs like '>:-))'.
438.1.6 by franku
run the script
160
        return '> ' + text.replace('\r', '').replace('\n', '\n> ') + '\n'
209.1.68 by Timo Wingender
add field to choose between markdown and bbcode as markup
161
    elif markup == 'bbcode':
162
        return '[quote]\n%s\n[/quote]\n' % text
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
163
    else:
164
        return text
165
166
167
def unescape(text):
438.1.6 by franku
run the script
168
    """Do reverse escaping."""
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
169
170
    text = text.replace('&', '&')
171
    text = text.replace('&lt;', '<')
172
    text = text.replace('&gt;', '>')
173
    text = text.replace('&quot;', '"')
174
    text = text.replace('&#39;', '\'')
175
    return text