37
37
# We will also need the site domain
38
38
from django.contrib.sites.models import Site
39
39
from settings import SITE_ID, SMILEYS, SMILEY_DIR, \
40
SMILEY_PREESCAPING, BZR_URL
40
SMILEY_PREESCAPING, BZR_URL
43
43
_domain = Site.objects.get(pk=SITE_ID).domain
47
47
# Getting local domain lists
49
49
from settings import LOCAL_DOMAINS as _LOCAL_DOMAINS
50
LOCAL_DOMAINS = [ _domain ] + _LOCAL_DOMAINS
50
LOCAL_DOMAINS = [_domain] + _LOCAL_DOMAINS
51
51
except ImportError:
52
LOCAL_DOMAINS = [ _domain ]
52
LOCAL_DOMAINS = [_domain]
55
55
register = template.Library()
57
def _insert_smileys( text ):
59
This searches for smiley symbols in the current text
60
and replaces them with the correct images.
58
def _insert_smileys(text):
59
"""This searches for smiley symbols in the current text and replaces them
60
with the correct images.
61
62
Only replacing if smiley symbols aren't in a word (e.g. http://....)
63
words = text.split(" ")
64
for sc,img in SMILEYS:
65
words = text.split(' ')
66
for sc, img in SMILEYS:
66
words[words.index(sc)] = "<img src='%s%s' alt='%s' />" % ( SMILEY_DIR, img, img )
67
text = " ".join(words)
69
sc)] = "<img src='%s%s' alt='%s' />" % (SMILEY_DIR, img, img)
70
text = ' '.join(words)
70
def _insert_smiley_preescaping( text ):
72
This searches for smiley symbols in the current text
73
and replaces them with the correct images
75
for before,after in SMILEY_PREESCAPING:
76
text = text.replace(before,after)
74
def _insert_smiley_preescaping(text):
75
"""This searches for smiley symbols in the current text and replaces them
76
with the correct images."""
77
for before, after in SMILEY_PREESCAPING:
78
text = text.replace(before, after)
81
re.compile( "bzr:r(\d+)" ),
83
re.compile('bzr:r(\d+)'),
84
def _insert_revision( text ):
87
def _insert_revision(text):
85
88
for r in revisions_re:
86
89
text = r.sub( lambda m: """<a href="%s">r%s</a>""" % (
87
90
settings.BZR_URL % m.group(1), m.group(1)), text)
90
def _classify_link( tag ):
92
Returns a classname to insert if this link is in any way
93
special (external or missing wikipages)
94
def _classify_link(tag):
95
"""Returns a classname to insert if this link is in any way special
96
(external or missing wikipages)
95
98
tag to classify for
97
101
# No class change for image links
98
if tag.findChild("img") != None:
102
if tag.findChild('img') != None:
101
href = tag["href"].lower()
105
href = tag['href'].lower()
103
107
# Check for external link
104
if href.startswith("http"):
108
if href.startswith('http'):
105
109
for domain in LOCAL_DOMAINS:
107
111
if href.find(domain) != -1:
111
return { 'class': "externalLink", 'title': "This link refers to outer space" }
113
if "/profile/" in (tag["href"]):
114
return { 'class': "userLink", 'title': "This link refers to a userpage" }
117
if check_for_missing_wikipages and href.startswith("/wiki/"):
115
return {'class': 'externalLink', 'title': 'This link refers to outer space'}
117
if '/profile/' in (tag['href']):
118
return {'class': 'userLink', 'title': 'This link refers to a userpage'}
120
if check_for_missing_wikipages and href.startswith('/wiki/'):
119
122
# Check for missing wikilink /wiki/PageName[/additionl/stuff]
120
123
# Using href because we need cAsEs here
121
pn = tag["href"][6:].split('/',1)[0]
123
if not len(pn): # Wiki root link is not a page
124
return { 'class': "wrongLink", 'title': "This Link misses an articlename"}
124
pn = tag['href'][6:].split('/', 1)[0]
126
if not len(pn): # Wiki root link is not a page
127
return {'class': 'wrongLink', 'title': 'This Link misses an articlename'}
126
129
# Wiki special pages are also not counted
127
if pn in ["list","search","history","feeds","observe","edit" ]:
128
return { 'class': "specialLink" }
130
if pn in ['list', 'search', 'history', 'feeds', 'observe', 'edit']:
131
return {'class': 'specialLink'}
130
133
# Check for a redirect
132
135
# try to get the article id; if this fails an IndexError is raised
133
a_id = ChangeSet.objects.filter( old_title=pn ).values_list('article_id')[0]
136
a_id = ChangeSet.objects.filter(
137
old_title=pn).values_list('article_id')[0]
135
139
# get actual title of article
136
act_t = Article.objects.get( id=a_id[0] ).title
140
act_t = Article.objects.get(id=a_id[0]).title
138
return { 'title': "This is a redirect and points to \"" + act_t + "\"" }
142
return {'title': "This is a redirect and points to \"" + act_t + "\""}
141
145
except IndexError:
144
148
# article missing (or misspelled)
145
149
if Article.objects.filter(title=pn).count() == 0:
146
return { 'class': "missingLink", 'title': "This Link is misspelled or missing. Click to create it anyway." }
150
return {'class': 'missingLink', 'title': 'This Link is misspelled or missing. Click to create it anyway.'}
150
def _clickable_image( tag ):
155
def _clickable_image(tag):
151
156
# is external link?
152
if tag["src"].startswith("http"):
157
if tag['src'].startswith('http'):
154
159
if tag.parent.name != 'a':
155
160
# add link to image
156
text = "<a href=" + tag["src"] +"><img src=" + tag["src"] + "></a>"
161
text = '<a href=' + tag['src'] + \
162
'><img src=' + tag['src'] + '></a>'
162
168
# Wikiwordification
163
169
# Match a wiki page link LikeThis. All !WikiWords (with a !
164
170
# in front) are ignored
165
"wikiwords": (re.compile(r"(!?)(\b[A-Z][a-z]+[A-Z]\w+\b)"), lambda m:
166
m.group(2) if m.group(1) == '!' else
167
u"""<a href="/wiki/%(match)s">%(match)s</a>""" %
168
{"match": m.group(2) }),
171
'wikiwords': (re.compile(r"(!?)(\b[A-Z][a-z]+[A-Z]\w+\b)"), lambda m:
172
m.group(2) if m.group(1) == '!' else
173
u"""<a href="/wiki/%(match)s">%(match)s</a>""" %
174
{'match': m.group(2)}),
172
def do_wl_markdown( value, *args, **keyw ):
179
def do_wl_markdown(value, *args, **keyw):
173
180
# Do Preescaping for markdown, so that some things stay intact
174
181
# This is currently only needed for this smiley ">:-)"
175
value = _insert_smiley_preescaping( value )
182
value = _insert_smiley_preescaping(value)
176
183
custom = keyw.pop('custom', True)
177
html = smart_str(markdown(value, extensions=["extra","toc"], *args, **keyw))
184
html = smart_str(markdown(value, extensions=[
185
'extra', 'toc'], *args, **keyw))
179
187
# Sanitize posts from potencial untrusted users (Forum/Wiki/Maps)
180
188
if 'bleachit' in args:
181
html = mark_safe(bleach.clean(html, tags=BLEACH_ALLOWED_TAGS, attributes=BLEACH_ALLOWED_ATTRIBUTES))
189
html = mark_safe(bleach.clean(
190
html, tags=BLEACH_ALLOWED_TAGS, attributes=BLEACH_ALLOWED_ATTRIBUTES))
183
192
# Since we only want to do replacements outside of tags (in general) and not between
184
193
# <a> and </a> we partition our site accordingly