| 1 |
import os |
|---|
| 2 |
import re |
|---|
| 3 |
import datetime |
|---|
| 4 |
import urlparse |
|---|
| 5 |
from django.conf import settings |
|---|
| 6 |
from django.core.cache import cache |
|---|
| 7 |
from django.http import Http404, HttpResponseRedirect |
|---|
| 8 |
from django.shortcuts import get_object_or_404, render_to_response |
|---|
| 9 |
from django.template import RequestContext |
|---|
| 10 |
from django_website.apps.docs.models import DocumentRelease |
|---|
| 11 |
from django_website.apps.docs import builder |
|---|
| 12 |
import pysvn |
|---|
| 13 |
|
|---|
| 14 |
REVISION = pysvn.Revision(pysvn.opt_revision_kind.number, 8503) |
|---|
| 15 |
|
|---|
| 16 |
def doc_index(request, version=None): |
|---|
| 17 |
client, version, docroot = _get_svnroot(version, "docs/") |
|---|
| 18 |
doclist = client.ls(docroot, recurse=False, revision=REVISION) |
|---|
| 19 |
|
|---|
| 20 |
# Convert list of URLs to list of document slugs. |
|---|
| 21 |
doclist = [os.path.splitext(os.path.basename(doc.name))[0] for doc in doclist] |
|---|
| 22 |
doclist.sort() |
|---|
| 23 |
|
|---|
| 24 |
return render_to_response( |
|---|
| 25 |
["docs/%s_index.html" % version, "docs/index.html"], |
|---|
| 26 |
{"version" : version, "document_list" : doclist, "all_versions" : DocumentRelease.objects.all()}, |
|---|
| 27 |
RequestContext(request, {}) |
|---|
| 28 |
) |
|---|
| 29 |
|
|---|
| 30 |
def doc_detail(request, slug, version=None): |
|---|
| 31 |
client, version, docroot = _get_svnroot(version, "docs/") |
|---|
| 32 |
|
|---|
| 33 |
docpath = urlparse.urljoin(docroot, slug+".txt") |
|---|
| 34 |
try: |
|---|
| 35 |
name, info = client.info2(docpath, revision=REVISION)[0] |
|---|
| 36 |
except pysvn.ClientError: |
|---|
| 37 |
raise Http404("Invalid doc: %r (version %r)" % (slug, version)) |
|---|
| 38 |
|
|---|
| 39 |
cache_key = "djangowebsite:docs:%s:%s:%s" % (version, slug, info.rev.number) |
|---|
| 40 |
parts = cache.get(cache_key) |
|---|
| 41 |
if parts is None: |
|---|
| 42 |
parts = builder.build_document(client.cat(docpath, revision=REVISION)) |
|---|
| 43 |
cache.set(cache_key, parts, 60*60) |
|---|
| 44 |
|
|---|
| 45 |
template_list = ["docs/%s_detail.html" % version, "docs/detail.html"] |
|---|
| 46 |
context = { |
|---|
| 47 |
"doc" : parts, |
|---|
| 48 |
"version" : version, |
|---|
| 49 |
"all_versions" : DocumentRelease.objects.all(), |
|---|
| 50 |
"slug" : slug, |
|---|
| 51 |
"update_date" : datetime.datetime.fromtimestamp(info.last_changed_date), |
|---|
| 52 |
} |
|---|
| 53 |
return render_to_response(template_list, context, RequestContext(request, {})) |
|---|
| 54 |
|
|---|
| 55 |
docstring_re = re.compile(r"([\"']{3})(.*?)(\1)", re.DOTALL|re.MULTILINE) |
|---|
| 56 |
def model_index(request, version=None): |
|---|
| 57 |
client, version, testroot = _get_svnroot(version, "tests/modeltests/") |
|---|
| 58 |
|
|---|
| 59 |
cache_key = "djangowebsite:docs:modelindex:%s" % version |
|---|
| 60 |
model_docs = cache.get(cache_key, []) |
|---|
| 61 |
if not model_docs: |
|---|
| 62 |
for testdir in client.ls(testroot, revision=REVISION): |
|---|
| 63 |
try: |
|---|
| 64 |
content = client.cat(os.path.join(testdir.name, "models.py"), revision=REVISION) |
|---|
| 65 |
except pysvn.ClientError: |
|---|
| 66 |
continue |
|---|
| 67 |
|
|---|
| 68 |
try: |
|---|
| 69 |
title, blurb = docstring_re.match(content).group(2).strip().split('\n', 1) |
|---|
| 70 |
except (AttributeError, ValueError): |
|---|
| 71 |
continue # Skip models that don't have docstrings. |
|---|
| 72 |
|
|---|
| 73 |
try: |
|---|
| 74 |
number, title = title.split(". ", 1) |
|---|
| 75 |
number = int(number) |
|---|
| 76 |
except ValueError: |
|---|
| 77 |
continue |
|---|
| 78 |
model_docs.append({"title" : title, "link" : os.path.basename(testdir.name), "number" : number}) |
|---|
| 79 |
|
|---|
| 80 |
model_docs.sort(lambda a,b: cmp(a["number"], b["number"])) |
|---|
| 81 |
|
|---|
| 82 |
cache.set(cache_key, model_docs, 60*60) |
|---|
| 83 |
|
|---|
| 84 |
return render_to_response( |
|---|
| 85 |
["docs/%s_model_index.html" % version, "docs/model_index.html"], |
|---|
| 86 |
{"example_list" : model_docs, "version" : version, "all_versions" : DocumentRelease.objects.all()}, |
|---|
| 87 |
RequestContext(request, {}) |
|---|
| 88 |
) |
|---|
| 89 |
|
|---|
| 90 |
def model_detail(request, slug, version=None): |
|---|
| 91 |
client, version, modelfile = _get_svnroot(version, "tests/modeltests/%s/models.py" % slug) |
|---|
| 92 |
name, info = client.info2(modelfile, revision=REVISION)[0] |
|---|
| 93 |
|
|---|
| 94 |
cache_key = "djangowebsite:docs:model:%s:%s:%s" % (version, slug, info.rev.number) |
|---|
| 95 |
parts = cache.get(cache_key) |
|---|
| 96 |
if parts is None: |
|---|
| 97 |
parts = builder.build_model_document(client.cat(modelfile, revision=REVISION)) |
|---|
| 98 |
cache.set(cache_key, parts, 60*60) |
|---|
| 99 |
|
|---|
| 100 |
return render_to_response( |
|---|
| 101 |
["docs/%s_model_detail.html" % version, "docs/model_detail.html"], |
|---|
| 102 |
{"doc" : parts, "version" : version, "all_versions" : DocumentRelease.objects.all(), "slug" : slug}, |
|---|
| 103 |
) |
|---|
| 104 |
|
|---|
| 105 |
def _get_svnroot(version, subpath): |
|---|
| 106 |
client = pysvn.Client() |
|---|
| 107 |
|
|---|
| 108 |
if version is None: |
|---|
| 109 |
version = "trunk" |
|---|
| 110 |
subpath = os.path.join("trunk/", subpath) |
|---|
| 111 |
else: |
|---|
| 112 |
rel = get_object_or_404(DocumentRelease, version=version) |
|---|
| 113 |
subpath = os.path.join(rel.repository_path, subpath) |
|---|
| 114 |
docroot = urlparse.urljoin(settings.DJANGO_SVN_ROOT, subpath) |
|---|
| 115 |
|
|---|
| 116 |
try: |
|---|
| 117 |
client.info2(docroot, recurse=False, revision=REVISION) |
|---|
| 118 |
except pysvn.ClientError: |
|---|
| 119 |
raise Http404("Bad SVN path: %s" % docroot) |
|---|
| 120 |
|
|---|
| 121 |
return client, version, docroot |
|---|