5
5
from django.conf import settings
6
6
from django.core.cache import cache
7
7
from django.template import RequestContext
8
from django.urls import reverse
8
from django.core.urlresolvers import reverse
9
9
from django.http import (Http404, HttpResponseRedirect,
10
10
HttpResponseNotAllowed, HttpResponse, HttpResponseForbidden)
11
from django.shortcuts import get_object_or_404, render, redirect
11
from django.shortcuts import get_object_or_404, render_to_response, redirect
12
12
from django.contrib.contenttypes.models import ContentType
13
from django.contrib import messages
14
14
from wiki.forms import ArticleForm
15
15
from wiki.models import Article, ChangeSet, dmp
17
17
from wiki.utils import get_ct
18
18
from django.contrib.auth.decorators import login_required
19
19
from mainpage.templatetags.wl_markdown import do_wl_markdown
20
from markdownextensions.semanticwikilinks.mdx_semanticwikilinks import WIKILINK_RE
22
21
from wl_utils import get_real_ip
27
24
# lock duration in minutes
67
64
url = reverse(urlname, urlconf, kwargs=kw)
68
65
return ''.join(['/', app, url]) # @@@ harcoded: /app/.../
67
# NOCOMM Franku: This Class is currently not used
68
# If we want this it has to be checked for the changes
69
# related to django 1.8.
70
# A javascript alert box is maybe a better solution
71
73
class ArticleEditLock(object):
72
74
"""A soft lock to edting an article."""
73
# TODO(Franku): This Class is currently not used
74
# If we want this it has to be checked for the changes
75
# related to django 1.8.
76
# A javascript alert box is maybe a better solution
77
76
def __init__(self, title, request, message_template=None):
79
78
self.user_ip = get_real_ip(request)
155
154
if extra_context is not None:
156
155
template_params.update(extra_context)
158
return render(request, '/'.join([template_dir, template_name]),
157
return render_to_response('/'.join([template_dir, template_name]),
159
context_instance=RequestContext(request))
160
160
return HttpResponseNotAllowed(['GET'])
223
223
if extra_context is not None:
224
224
template_params.update(extra_context)
226
return render(request, '/'.join([template_dir, template_name]),
226
return render_to_response('/'.join([template_dir, template_name]),
228
context_instance=RequestContext(request))
228
229
return HttpResponseNotAllowed(['GET'])
259
260
return HttpResponseForbidden()
262
# Try to fetch an existing article
263
263
article = article_qs.get(**article_args)
264
264
except ArticleClass.DoesNotExist:
265
# No article found, maybe we have a redirect
267
cs = ChangeSet.objects.filter(old_title=title)[0]
268
article = article_qs.get(title=cs.article)
270
# No Article found and no redirect found
273
267
if request.method == 'POST':
275
269
form = ArticleFormClass(request.POST, instance=article)
277
271
form.cache_old_content()
278
272
if form.is_valid():
280
if request.user.is_authenticated:
274
# NOCOMM Franku: This has never worked as i know and is IMHO
275
# useless. This code works with django 1.8 but misses some code
277
# https://docs.djangoproject.com/en/1.8/ref/contrib/messages/#module-django.contrib.messages
279
if request.user.is_authenticated():
281
280
form.editor = request.user
281
# if article is None:
282
# user_message = u"Your article was created successfully."
284
# user_message = u"Your article was edited successfully."
285
# messages.success(request, user_message)
283
287
if ((article is None) and (group_slug is not None)):
284
288
form.group = group
286
290
new_article, changeset = form.save()
288
if notification and not changeset.reverted:
289
# Get observers for this article and exclude current editor
290
items = notification.ObservedItem.objects.all_for(
291
new_article, 'post_save').exclude(user=request.user).iterator()
292
users = [o.user for o in items]
293
notification.send(users, 'wiki_observed_article_changed',
294
{'editor': request.user,
295
'rev': changeset.revision,
296
'rev_comment': changeset.comment,
297
'article': new_article})
300
292
return redirect(new_article)
302
294
elif request.method == 'GET':
295
user_ip = get_real_ip(request)
304
# TODO(Franku): Never worked IMHO
297
# NOCOMM FrankU: Never worked IMHO
305
298
# lock = cache.get(title, None)
306
299
# if lock is None:
307
300
# lock = ArticleEditLock(title, request)
308
301
# lock.create_message(request)
303
initial = {'user_ip': user_ip}
310
304
if group_slug is not None:
311
305
initial.update({'content_type': group_ct.id,
312
306
'object_id': group.id})
333
327
if extra_context is not None:
334
328
template_params.update(extra_context)
336
return render(request, '/'.join([template_dir, template_name]),
330
return render_to_response('/'.join([template_dir, template_name]),
332
context_instance=RequestContext(request))
340
335
def view_changeset(request, title, revision,
398
393
if extra_context is not None:
399
394
template_params.update(extra_context)
401
return render(request, '/'.join([template_dir, template_name]),
396
return render_to_response('/'.join([template_dir, template_name]),
398
context_instance=RequestContext(request))
403
399
return HttpResponseNotAllowed(['GET'])
443
439
if extra_context is not None:
444
440
template_params.update(extra_context)
446
return render(request, '/'.join([template_dir, template_name]),
442
return render_to_response('/'.join([template_dir, template_name]),
444
context_instance=RequestContext(request))
449
446
return HttpResponseNotAllowed(['GET'])
482
479
article = get_object_or_404(article_qs, **article_args)
485
# Check whether there is another Article with the same name to which this article
486
# wants to be reverted to. If so: prevent it and show a message.
487
old_title = article.changeset_set.filter(
488
revision=revision+1).get().old_title
490
art = Article.objects.exclude(pk=article.pk).get(title=old_title)
491
except Article.DoesNotExist:
492
# No existing article found -> reverting possible
493
if request.user.is_authenticated:
494
article.revert_to(revision, request.user)
496
article.revert_to(revision)
497
return redirect(article)
498
# An article with this name exists
500
request, 'Reverting not possible because an article with name \'%s\' already exists' % old_title)
481
if request.user.is_authenticated():
482
article.revert_to(revision, get_real_ip(request), request.user)
484
article.revert_to(revision, get_real_ip(request))
486
# NOCOMM Franku: This has never worked as i know and is IMHO
487
# useless. If we want this it has to be fixed for django 1.8
488
# See comment in edit_article()
489
# if request.user.is_authenticated():
490
# request.user.message_set.create(
491
# message=u"The article was reverted successfully.")
501
493
return redirect(article)
503
495
return HttpResponseNotAllowed(['POST'])
534
526
if extra_context is not None:
535
527
template_params.update(extra_context)
537
return render(request, '/'.join([template_dir, template_name]),
529
return render_to_response('/'.join([template_dir, template_name]),
531
context_instance=RequestContext(request))
539
532
return HttpResponseNotAllowed(['GET'])
629
622
dmp.diff_cleanupSemantic(diffs)
631
624
return HttpResponse(dmp.diff_prettyHtml(diffs), content_type='text/html')
634
def backlinks(request, title):
635
"""Search for links in other wiki articles pointing to the
639
# Find old title(s) of this article
640
this_article = get_object_or_404(Article, title=title)
641
changesets = this_article.changeset_set.all()
643
for cs in changesets:
644
if cs.old_title and cs.old_title != title and cs.old_title not in old_titles:
645
old_titles.append(cs.old_title)
647
# Search for semantic wiki links. The regexpr was copied from there
648
# and slightly modified
649
search_title = [re.compile(r"\[\[\s*(%s)/?\s*(\|\s*.+?\s*)?\]\]" % title)]
651
# Search for links in MarkDown syntax, like [Foo](wiki/FooBar)
652
# The regexpr matches the title between '/' and ')'
653
search_title.append(re.compile(r"\/%s\)" % title))
655
# Search for current and previous titles
658
articles_all = Article.objects.all().exclude(title=title)
659
for article in articles_all:
660
for regexp in search_title:
661
# Need to unqoute the content to match
662
# e.g. [[ Back | Title%20of%20Page ]]
663
match = regexp.search(urllib.unquote(article.content))
665
found_links.append({'title': article.title})
667
for old_title in old_titles:
668
if old_title in article.content:
669
found_old_links.append(
670
{'old_title': old_title, 'title': article.title })
672
context = {'found_links': found_links,
673
'found_old_links': found_old_links,
675
'article': this_article,
677
return render(request, 'wiki/backlinks.html',