Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Updated the update_docs management command to also reindex.

  • Loading branch information...
commit c87bb5ebe36e8d2c97944ee9d5670dc82e041923 1 parent aaa0a6e
Jacob Kaplan-Moss authored February 01, 2011
77  django_website/docs/management/commands/update_docs.py
@@ -4,32 +4,43 @@
4 4
 """
5 5
 from __future__ import absolute_import
6 6
 
  7
+import json
  8
+import haystack
7 9
 import subprocess
8 10
 import sphinx.cmdline
9 11
 from django.conf import settings
10 12
 from django.core.management.base import NoArgsCommand
  13
+from django.utils.html import strip_tags
11 14
 from unipath import FSPath as Path
12  
-from ...models import DocumentRelease
  15
+from ...models import DocumentRelease, Document
13 16
 
14 17
 class Command(NoArgsCommand):
15 18
     def handle_noargs(self, **kwargs):
16 19
         try:
17  
-            verbose = int(kwargs['verbosity']) > 0
  20
+            verbosity = int(kwargs['verbosity'])
18 21
         except (KeyError, TypeError, ValueError):
19  
-            verbose = True
  22
+            verbosity = 1
20 23
         
21 24
         for release in DocumentRelease.objects.all():
22  
-            if verbose:
  25
+            if verbosity >= 1:
23 26
                 print "Updating %s..." % release
24  
-                
  27
+            
25 28
             destdir = Path(settings.DOCS_BUILD_ROOT).child(release.lang, release.version)
26 29
             if not destdir.exists():
27 30
                 destdir.mkdir(parents=True)
  31
+
  32
+            #
  33
+            # Update the release from SCM.
  34
+            #
28 35
             
29 36
             # Make an SCM checkout/update into the destination directory.
30 37
             # Do this dynamically in case we add other SCM later.
31 38
             getattr(self, 'update_%s' % release.scm)(release.scm_url, destdir)
32 39
             
  40
+            #
  41
+            # Use Sphinx to build the release docs into JSON documents.
  42
+            #
  43
+
33 44
             # Make the directory for the JSON files - sphinx-build doesn't
34 45
             # do it for us, apparently.
35 46
             json_build_dir = destdir.child('_build', 'json')
@@ -44,5 +55,61 @@ def handle_noargs(self, **kwargs):
44 55
                 json_build_dir,    # Destination directory
45 56
             ])
46 57
 
  58
+            #
  59
+            # Rebuild the imported document list and search index.
  60
+            #
  61
+
  62
+            # Build a dict of {path_fragment: document_object}. We'll pop values
  63
+            # out of this dict as we go which'll make sure we know which
  64
+            # remaining documents need to be deleted (and unindexed) later on.
  65
+            documents = dict((doc.path, doc) for doc in release.documents.all())
  66
+
  67
+            # Walk the tree we've just built looking for ".fjson" documents
  68
+            # (just JSON, but Sphinx names them weirdly). Each one of those 
  69
+            # documents gets a corresponding Document object created which
  70
+            # we'll then ask Sphinx to reindex. 
  71
+            #
  72
+            # We have to be a bit careful to reverse-engineer the correct
  73
+            # relative path component, especially for "index" documents,
  74
+            # otherwise the search results will be incorrect. 
  75
+            for built_doc in json_build_dir.walk():
  76
+                if built_doc.isfile() and built_doc.ext == '.fjson':
  77
+                    
  78
+                    # Convert the built_doc path which is now an absolute
  79
+                    # path (i.e. "/home/docs/en/1.2/_build/ref/models.json")
  80
+                    # into a path component (i.e. "ref/models").
  81
+                    path = json_build_dir.rel_path_to(built_doc) 
  82
+                    if path.stem == 'index':
  83
+                        path = path.parent
  84
+                    path = str(path.parent.child(path.stem))
  85
+
  86
+                    # Read out the content and create a new Document object for
  87
+                    # it. We'll strip the HTML tags here (for want of a better
  88
+                    # place to do it).
  89
+                    with open(built_doc) as fp:
  90
+                        json_doc = json.load(fp)
  91
+                        try:
  92
+                            body = strip_tags(json_doc['body'])
  93
+                            title = strip_tags(json_doc['title'])
  94
+                        except KeyError, ex:
  95
+                            if verbosity >= 2:
  96
+                                print "Skipping: %s (no %s)" % (path, ex.args[0])
  97
+                            continue
  98
+
  99
+                    doc = documents.pop(path, Document(path=path, release=release))
  100
+                    doc.title = title
  101
+                    doc.body = body
  102
+                    if verbosity >= 2:
  103
+                        print "Indexing:", doc
  104
+                    doc.save()
  105
+                    haystack.site.update_object(doc)
  106
+
  107
+            # Clean up any remaining documents.
  108
+            for doc in documents.values():
  109
+                if verbosity >= 2:
  110
+                    print "Deleting:", doc
  111
+                haystack.site.remove_object(doc)
  112
+                doc.delete()
  113
+
47 114
     def update_svn(self, url, destdir):
48 115
         subprocess.call(['svn', 'checkout', '-q', url, destdir])

0 notes on commit c87bb5e

Please sign in to comment.
Something went wrong with that request. Please try again.