Allow unsafe inline style on docs
[pgweb/local.git] / pgweb / docs / views.py
blob6cfb186092ebf7acd43b1a4f687074aedaf7e9e9
1 from django.shortcuts import render, get_object_or_404
2 from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
3 from django.http import Http404
4 from pgweb.util.decorators import login_required, allow_frames, content_sources
5 from django.db.models import Q
6 from django.conf import settings
8 from decimal import Decimal
9 import os
11 from pgweb.util.contexts import render_pgweb
12 from pgweb.util.helpers import template_to_string
13 from pgweb.util.misc import send_template_mail
15 from pgweb.core.models import Version
17 from models import DocPage
18 from forms import DocCommentForm
20 @allow_frames
21 @content_sources('style', "'unsafe-inline'")
22 def docpage(request, version, filename):
23 loaddate = None
24 # Get the current version both to map the /current/ url, and to later
25 # determine if we allow comments on this page.
26 currver = Version.objects.filter(current=True)[0].tree
27 if version == 'current':
28 ver = currver
29 elif version == 'devel':
30 ver = Decimal(0)
31 loaddate = Version.objects.get(tree=Decimal(0)).docsloaded
32 else:
33 ver = Decimal(version)
34 if ver == Decimal(0):
35 raise Http404("Version not found")
37 if ver < Decimal("7.1") and ver > Decimal(0):
38 extension = "htm"
39 else:
40 extension = "html"
42 if ver < Decimal("7.1") and ver > Decimal(0):
43 indexname = "postgres.htm"
44 elif ver == Decimal("7.1"):
45 indexname = "postgres.html"
46 else:
47 indexname = "index.html"
49 if ver >= 10 and version.find('.') > -1:
50 # Version 10 and up, but specified as 10.0 / 11.0 etc, so redirect back without the
51 # decimal.
52 return HttpResponsePermanentRedirect("/docs/{0}/{1}.html".format(int(ver), filename))
54 fullname = "%s.%s" % (filename, extension)
55 page = get_object_or_404(DocPage, version=ver, file=fullname)
56 versions = DocPage.objects.extra(
57 where=["file=%s OR file IN (SELECT file2 FROM docsalias WHERE file1=%s) OR file IN (SELECT file1 FROM docsalias WHERE file2=%s)"],
58 params=[fullname, fullname, fullname],
59 select={
60 'supported':"COALESCE((SELECT supported FROM core_version v WHERE v.tree=version), 'f')",
61 'testing':"COALESCE((SELECT testing FROM core_version v WHERE v.tree=version),0)",
62 }).order_by('-supported', 'version').only('version', 'file')
64 return render(request, 'docs/docspage.html', {
65 'page': page,
66 'supported_versions': [v for v in versions if v.supported],
67 'devel_versions': [v for v in versions if not v.supported and v.testing],
68 'unsupported_versions': [v for v in versions if not v.supported and not v.testing],
69 'title': page.title,
70 'doc_index_filename': indexname,
71 'loaddate': loaddate,
74 def docspermanentredirect(request, version, typ, page, *args):
75 """Provides a permanent redirect from the old static/interactive pages to
76 the modern pages that do not have said keywords.
77 """
78 url = "/docs/%s/" % version
79 if page:
80 url += page
81 return HttpResponsePermanentRedirect(url)
83 def docsrootpage(request, version):
84 return docpage(request, version, 'index')
86 def redirect_root(request, version):
87 return HttpResponsePermanentRedirect("/docs/%s/" % version)
89 def root(request):
90 versions = Version.objects.filter(Q(supported=True) | Q(testing__gt=0,tree__gt=0)).order_by('-tree')
91 return render_pgweb(request, 'docs', 'docs/index.html', {
92 'versions': versions,
95 class _VersionPdfWrapper(object):
96 """
97 A wrapper around a version that knows to look for PDF files, and
98 return their sizes.
99 """
100 def __init__(self, version):
101 self.__version = version
102 self.a4pdf = self._find_pdf('A4')
103 self.uspdf = self._find_pdf('US')
104 # Some versions have, ahem, strange index filenames
105 if self.__version.tree < Decimal('6.4'):
106 self.indexname = 'book01.htm'
107 elif self.__version.tree < Decimal('7.0'):
108 self.indexname = 'postgres.htm'
109 elif self.__version.tree < Decimal('7.2'):
110 self.indexname = 'postgres.html'
111 else:
112 self.indexname = 'index.html'
113 def __getattr__(self, name):
114 return getattr(self.__version, name)
115 def _find_pdf(self, pagetype):
116 try:
117 return os.stat('%s/documentation/pdf/%s/postgresql-%s-%s.pdf' % (settings.STATIC_CHECKOUT, self.__version.numtree, self.__version.numtree, pagetype)).st_size
118 except:
119 return 0
121 def manuals(request):
122 versions = Version.objects.filter(Q(supported=True) | Q(testing__gt=0,tree__gt=0)).order_by('-tree')
123 return render_pgweb(request, 'docs', 'docs/manuals.html', {
124 'versions': [_VersionPdfWrapper(v) for v in versions],
127 def manualarchive(request):
128 versions = Version.objects.filter(testing=0,supported=False,tree__gt=0).order_by('-tree')
129 return render_pgweb(request, 'docs', 'docs/archive.html', {
130 'versions': [_VersionPdfWrapper(v) for v in versions],
133 @login_required
134 def commentform(request, itemid, version, filename):
135 v = get_object_or_404(Version, tree=version)
136 if not v.supported:
137 # No docs comments on unsupported versions
138 return HttpResponseRedirect("/docs/{0}/{1}".format(version, filename))
140 if request.method == 'POST':
141 form = DocCommentForm(request.POST)
142 if form.is_valid():
143 if version == '0.0':
144 version = 'devel'
146 send_template_mail(
147 settings.DOCSREPORT_NOREPLY_EMAIL,
148 settings.DOCSREPORT_EMAIL,
149 '%s' % form.cleaned_data['shortdesc'],
150 'docs/docsbugmail.txt', {
151 'version': version,
152 'filename': filename,
153 'details': form.cleaned_data['details'],
155 usergenerated=True,
156 cc=form.cleaned_data['email'],
157 replyto='%s, %s' % (form.cleaned_data['email'], settings.DOCSREPORT_EMAIL),
158 sendername='PG Doc comments form'
160 return render_pgweb(request, 'docs', 'docs/docsbug_completed.html', {})
161 else:
162 form = DocCommentForm(initial={
163 'name': '%s %s' % (request.user.first_name, request.user.last_name),
164 'email': request.user.email,
167 return render_pgweb(request, 'docs', 'base/form.html', {
168 'form': form,
169 'formitemtype': 'documentation comment',
170 'operation': 'Submit',
171 'form_intro': template_to_string('docs/docsbug.html', {
172 'user': request.user,
174 'savebutton': 'Send Email',