def handle_noargs(self, **kwargs):
     try:
         verbose = int(kwargs['verbosity']) > 0
     except (KeyError, TypeError, ValueError):
         verbose = True
     
     for release in DocumentRelease.objects.all():
         if verbose:
             print "Updating %s..." % release
             
         destdir = Path(settings.DOCS_BUILD_ROOT).child(release.lang, release.version)
         if not destdir.exists():
             destdir.mkdir(parents=True)
         
         # Make an SCM checkout/update into the destination directory.
         # Do this dynamically in case we add other SCM later.
         getattr(self, 'update_%s' % release.scm)(release.scm_url, destdir)
         
         # Make the directory for the JSON files - sphinx-build doesn't
         # do it for us, apparently.
         json_build_dir = destdir.child('_build', 'json')
         if not json_build_dir.exists():
             json_build_dir.mkdir(parents=True)
         
         # "Shell out" (not exactly, but basically) to sphinx-build.
         sphinx.cmdline.main(['sphinx-build',
             '-b', 'json',      # Use the JSON builder
             '-q',              # Be vewy qwiet
             destdir,           # Source file directory
             json_build_dir,    # Destination directory
         ])
Ejemplo n.º 2
0
def dict2dir(dir, dic, mode="w"):
    dir = FSPath(dir)
    if not dir.exists():
        dir.mkdir()
    for filename, content in dic.iteritems():
        p = FSPath(dir, filename)
        if isinstance(content, dict):
            dict2dir(p, content)
            continue
        f = open(p, mode)
        f.write(content)
        f.close()
Ejemplo n.º 3
0
def require_dir(config, key, create_if_missing=False):
    from unipath import FSPath as Path
    try:
        dir = config[key]
    except KeyError:
        msg = "config option '%s' missing"
        raise KeyError(msg % key)
    dir = Path(config[key])
    if not dir.exists():
        dir.mkdir(parents=True)
    if not dir.isdir():
        msg = ("directory '%s' is missing or not a directory "
               "(from config option '%s')")
        tup = dir, key
        raise OSError(msg % tup)
Ejemplo n.º 4
0
def test_merge_trees(tmpdir):
    # Set up and merge two directory trees:
    #   src1/
    #       file1.txt
    #       dir1/
    #           file2.txt
    #           file3.txt
    #   src2/
    #       file1.txt
    #       dir1/
    #           file3.txt
    #           file4.txt
    #           dir2/
    #               file5.txt
    #
    # Expected output should be:
    #
    #   src1/
    #       file1.txt           <-- from src2
    #       dir1/
    #           file2.txt       <-- from src1
    #           file3.txt       <-- from src2
    #           file4.txt       <-- from src2
    #           dir2/
    #               file5.txt   <-- from src2

    src1 = Path(str(tmpdir)).child('src1')
    src1.mkdir()
    src1.child('file1.txt').write_file('src1: file1')
    src1.child('dir1').mkdir()
    src1.child('dir1', 'file2.txt').write_file('src1: file2')
    src1.child('dir1', 'file3.txt').write_file('src1: file3')

    src2 = Path(str(tmpdir)).child('src2')
    src2.mkdir()
    src2.child('file1.txt').write_file('src2: file1')
    src2.child('dir1').mkdir()
    src2.child('dir1', 'file3.txt').write_file('src2: file3')
    src2.child('dir1', 'file4.txt').write_file('src2: file4')
    src2.child('dir1', 'dir2').mkdir()
    src2.child('dir1', 'dir2', 'file5.txt').write_file('src2: file5')

    dest = Path(str(tmpdir)).child('dest')
    dest.mkdir()

    fileutils.merge_trees([src1, src2], dest)
    assert ls(dest) == ['dir1', 'file1.txt']
    assert dest.child('file1.txt').read_file() == 'src2: file1'
    assert ls(dest.child('dir1')) == ['dir2', 'file2.txt', 'file3.txt', 'file4.txt']
    assert dest.child('dir1', 'file2.txt').read_file() == 'src1: file2'
    assert dest.child('dir1', 'file3.txt').read_file() == 'src2: file3'
    assert ls(dest.child('dir1', 'dir2')) == ['file5.txt']
Ejemplo n.º 5
0
    def handle_noargs(self, **kwargs):
        try:
            verbosity = int(kwargs['verbosity'])
        except (KeyError, TypeError, ValueError):
            verbosity = 1

        builders = ['json', 'html']

        # Somehow, bizarely, there's a bug in Sphinx such that if I try to
        # build 1.0 before other versions, things fail in weird ways. However,
        # building newer versions first works. I suspect Sphinx is hanging onto
        # some global state. Anyway, we can work around it by making sure that
        # "dev" builds before "1.0". This is ugly, but oh well.
        for release in DocumentRelease.objects.order_by('-version'):
            if verbosity >= 1:
                print "Updating %s..." % release

            # checkout_dir is shared for all languages.
            checkout_dir = Path(settings.DOCS_BUILD_ROOT).child(release.version)
            parent_build_dir = Path(settings.DOCS_BUILD_ROOT).child(release.lang, release.version)
            if not checkout_dir.exists():
                checkout_dir.mkdir(parents=True)
            if not parent_build_dir.exists():
                parent_build_dir.mkdir(parents=True)

            #
            # Update the release from SCM.
            #

            # Make an SCM checkout/update into the destination directory.
            # Do this dynamically in case we add other SCM later.
            getattr(self, 'update_%s' % release.scm)(release.scm_url, checkout_dir)

            if release.docs_subdir:
                source_dir = checkout_dir.child(*release.docs_subdir.split('/'))
            else:
                source_dir = checkout_dir

            if release.lang != 'en':
                scm_url = release.scm_url.replace('django.git', 'django-docs-translations.git')
                trans_dir = checkout_dir.child('django-docs-translation')
                if not trans_dir.exists():
                    trans_dir.mkdir()
                getattr(self, 'update_%s' % release.scm)(scm_url, trans_dir)
                if not source_dir.child('locale').exists():
                    source_dir.child('locale').write_link(trans_dir.child('translations'))
                subprocess.call("cd %s && make translations" % trans_dir, shell=True)

            if release.is_default:
                # Build the pot files (later retrieved by Transifex)
                builders.append('gettext')

            #
            # Use Sphinx to build the release docs into JSON and HTML documents.
            #
            for builder in builders:
                # Wipe and re-create the build directory. See #18930.
                build_dir = parent_build_dir.child('_build', builder)
                if build_dir.exists():
                    shutil.rmtree(build_dir)
                build_dir.mkdir(parents=True)

                if verbosity >= 2:
                    print "  building %s (%s -> %s)" % (builder, source_dir, build_dir)
                subprocess.call(['sphinx-build',
                    '-b', builder,
                    '-D', 'language=%s' % release.lang,
                    '-q',              # Be vewy qwiet
                    source_dir,        # Source file directory
                    build_dir,         # Destination directory
                ])

            #
            # Create a zip file of the HTML build for offline reading.
            # This gets moved into MEDIA_ROOT for downloading.
            #
            html_build_dir = parent_build_dir.child('_build', 'html')
            zipfile_name = 'django-docs-%s-%s.zip' % (release.version, release.lang)
            zipfile_path = Path(settings.MEDIA_ROOT).child('docs', zipfile_name)
            if not zipfile_path.parent.exists():
                zipfile_path.parent.mkdir(parents=True)
            if verbosity >= 2:
                print "  build zip (into %s)" % zipfile_path

            def zipfile_inclusion_filter(f):
                return f.isfile() and '.doctrees' not in f.components()

            with closing(zipfile.ZipFile(zipfile_path, 'w')) as zf:
                for f in html_build_dir.walk(filter=zipfile_inclusion_filter):
                    zf.write(f, html_build_dir.rel_path_to(f))

            #
            # Copy the build results to the directory used for serving
            # the documentation in the least disruptive way possible.
            #
            build_dir = parent_build_dir.child('_build')
            built_dir = parent_build_dir.child('_built')
            subprocess.check_call(['rsync', '--archive', '--delete',
                    '--link-dest=' + build_dir, build_dir + '/', built_dir])

            #
            # Rebuild the imported document list and search index.
            #
            if not kwargs['reindex']:
                continue

            if verbosity >= 2:
                print "  reindexing..."

            # Build a dict of {path_fragment: document_object}. We'll pop values
            # out of this dict as we go which'll make sure we know which
            # remaining documents need to be deleted (and unindexed) later on.
            documents = dict((doc.path, doc) for doc in release.documents.all())

            # Walk the tree we've just built looking for ".fjson" documents
            # (just JSON, but Sphinx names them weirdly). Each one of those
            # documents gets a corresponding Document object created which
            # we'll then ask Sphinx to reindex.
            #
            # We have to be a bit careful to reverse-engineer the correct
            # relative path component, especially for "index" documents,
            # otherwise the search results will be incorrect.
            json_built_dir = parent_build_dir.child('_built', 'json')
            for built_doc in json_built_dir.walk():
                if built_doc.isfile() and built_doc.ext == '.fjson':

                    # Convert the built_doc path which is now an absolute
                    # path (i.e. "/home/docs/en/1.2/_built/ref/models.json")
                    # into a path component (i.e. "ref/models").
                    path = json_built_dir.rel_path_to(built_doc)
                    if path.stem == 'index':
                        path = path.parent
                    path = str(path.parent.child(path.stem))

                    # Read out the content and create a new Document object for
                    # it. We'll strip the HTML tags here (for want of a better
                    # place to do it).
                    with open(built_doc) as fp:
                        json_doc = json.load(fp)
                        try:
                            json_doc['body']  # Just to make sure it exists.
                            title = unescape_entities(strip_tags(json_doc['title']))
                        except KeyError, ex:
                            if verbosity >= 2:
                                print "Skipping: %s (no %s)" % (path, ex.args[0])
                            continue

                    doc = documents.pop(path, Document(path=path, release=release))
                    doc.title = title
                    doc.save()
                    haystack.site.update_object(doc)

            # Clean up any remaining documents.
            for doc in documents.values():
                if verbosity >= 2:
                    print "Deleting:", doc
                haystack.site.remove_object(doc)
                doc.delete()
Ejemplo n.º 6
0
    def handle_noargs(self, **kwargs):
        try:
            verbosity = int(kwargs['verbosity'])
        except (KeyError, TypeError, ValueError):
            verbosity = 1

        # Somehow, bizarely, there's a bug in Sphinx such that if I try to
        # build 1.0 before other versions, things fail in weird ways. However,
        # building newer versions first works. I suspect Sphinx is hanging onto
        # some global state. Anyway, we can work around it by making sure that
        # "dev" builds before "1.0". This is ugly, but oh well.
        for release in DocumentRelease.objects.order_by('-version'):
            if verbosity >= 1:
                print "Updating %s..." % release

            # checkout_dir is shared for all languages.
            checkout_dir = Path(settings.DOCS_BUILD_ROOT).child(
                release.version)
            parent_build_dir = Path(settings.DOCS_BUILD_ROOT).child(
                release.lang, release.version)
            if not checkout_dir.exists():
                checkout_dir.mkdir(parents=True)
            if not parent_build_dir.exists():
                parent_build_dir.mkdir(parents=True)

            #
            # Update the release from SCM.
            #

            # Make an SCM checkout/update into the destination directory.
            # Do this dynamically in case we add other SCM later.
            getattr(self, 'update_%s' % release.scm)(release.scm_url,
                                                     checkout_dir)

            if release.docs_subdir:
                source_dir = checkout_dir.child(
                    *release.docs_subdir.split('/'))
            else:
                source_dir = checkout_dir

            if release.lang != 'en':
                scm_url = release.scm_url.replace(
                    'django.git', 'django-docs-translations.git')
                trans_dir = checkout_dir.child('django-docs-translation')
                if not trans_dir.exists():
                    trans_dir.mkdir()
                getattr(self, 'update_%s' % release.scm)(scm_url, trans_dir)
                if not source_dir.child('locale').exists():
                    source_dir.child('locale').write_link(
                        trans_dir.child('translations'))
                subprocess.call("cd %s && make translations" % trans_dir,
                                shell=True)

            #
            # Use Sphinx to build the release docs into JSON and HTML documents.
            #
            for builder in ('json', 'html'):
                # Wipe and re-create the build directory. See #18930.
                build_dir = parent_build_dir.child('_build', builder)
                if build_dir.exists():
                    shutil.rmtree(build_dir)
                build_dir.mkdir(parents=True)

                # "Shell out" (not exactly, but basically) to sphinx-build.
                if verbosity >= 2:
                    print "  building %s (%s -> %s)" % (builder, source_dir,
                                                        build_dir)
                sphinx.cmdline.main([
                    'sphinx-build',
                    '-b',
                    builder,
                    '-D',
                    'language=%s' % release.lang,
                    '-q',  # Be vewy qwiet
                    source_dir,  # Source file directory
                    build_dir,  # Destination directory
                ])

            #
            # Create a zip file of the HTML build for offline reading.
            # This gets moved into MEDIA_ROOT for downloading.
            #
            html_build_dir = parent_build_dir.child('_build', 'html')
            zipfile_name = 'django-docs-%s-%s.zip' % (release.version,
                                                      release.lang)
            zipfile_path = Path(settings.MEDIA_ROOT).child(
                'docs', zipfile_name)
            if not zipfile_path.parent.exists():
                zipfile_path.parent.mkdir(parents=True)
            if verbosity >= 2:
                print "  build zip (into %s)" % zipfile_path

            def zipfile_inclusion_filter(f):
                return f.isfile() and '.doctrees' not in f.components()

            with closing(zipfile.ZipFile(zipfile_path, 'w')) as zf:
                for f in html_build_dir.walk(filter=zipfile_inclusion_filter):
                    zf.write(f, html_build_dir.rel_path_to(f))

            #
            # Copy the build results to the directory used for serving
            # the documentation in the least disruptive way possible.
            #
            build_dir = parent_build_dir.child('_build')
            built_dir = parent_build_dir.child('_built')
            subprocess.check_call([
                'rsync', '--archive', '--delete', '--link-dest=' + build_dir,
                build_dir + '/', built_dir
            ])

            #
            # Rebuild the imported document list and search index.
            #
            if not kwargs['reindex']:
                continue

            if verbosity >= 2:
                print "  reindexing..."

            # Build a dict of {path_fragment: document_object}. We'll pop values
            # out of this dict as we go which'll make sure we know which
            # remaining documents need to be deleted (and unindexed) later on.
            documents = dict(
                (doc.path, doc) for doc in release.documents.all())

            # Walk the tree we've just built looking for ".fjson" documents
            # (just JSON, but Sphinx names them weirdly). Each one of those
            # documents gets a corresponding Document object created which
            # we'll then ask Sphinx to reindex.
            #
            # We have to be a bit careful to reverse-engineer the correct
            # relative path component, especially for "index" documents,
            # otherwise the search results will be incorrect.
            json_built_dir = parent_build_dir.child('_built', 'json')
            for built_doc in json_built_dir.walk():
                if built_doc.isfile() and built_doc.ext == '.fjson':

                    # Convert the built_doc path which is now an absolute
                    # path (i.e. "/home/docs/en/1.2/_built/ref/models.json")
                    # into a path component (i.e. "ref/models").
                    path = json_built_dir.rel_path_to(built_doc)
                    if path.stem == 'index':
                        path = path.parent
                    path = str(path.parent.child(path.stem))

                    # Read out the content and create a new Document object for
                    # it. We'll strip the HTML tags here (for want of a better
                    # place to do it).
                    with open(built_doc) as fp:
                        json_doc = json.load(fp)
                        try:
                            json_doc['body']  # Just to make sure it exists.
                            title = unescape_entities(
                                strip_tags(json_doc['title']))
                        except KeyError, ex:
                            if verbosity >= 2:
                                print "Skipping: %s (no %s)" % (path,
                                                                ex.args[0])
                            continue

                    doc = documents.pop(path,
                                        Document(path=path, release=release))
                    doc.title = title
                    doc.save()
                    haystack.site.update_object(doc)

            # Clean up any remaining documents.
            for doc in documents.values():
                if verbosity >= 2:
                    print "Deleting:", doc
                haystack.site.remove_object(doc)
                doc.delete()
Ejemplo n.º 7
0
    def handle_noargs(self, **kwargs):
        try:
            verbosity = int(kwargs['verbosity'])
        except (KeyError, TypeError, ValueError):
            verbosity = 1

        for release in DocumentRelease.objects.all():
            if verbosity >= 1:
                print "Updating %s..." % release

            destdir = Path(settings.DOCS_BUILD_ROOT).child(release.lang, release.version)
            if not destdir.exists():
                destdir.mkdir(parents=True)

            #
            # Update the release from SCM.
            #

            # Make an SCM checkout/update into the destination directory.
            # Do this dynamically in case we add other SCM later.
            getattr(self, 'update_%s' % release.scm)(release.scm_url, destdir)

            #
            # Use Sphinx to build the release docs into JSON and HTML documents.
            #
            for builder in ('json', 'html'):
                # Make the directory for the built files - sphinx-build doesn't
                # do it for us, apparently.
                build_dir = destdir.child('_build', builder)
                if not build_dir.exists():
                    build_dir.mkdir(parents=True)

                # "Shell out" (not exactly, but basically) to sphinx-build.
                if verbosity >= 2:
                    print "  building %s (into %s)" % (builder, build_dir)
                sphinx.cmdline.main(['sphinx-build',
                    '-b', builder,
                    '-q',              # Be vewy qwiet
                    destdir,           # Source file directory
                    build_dir,         # Destination directory
                ])

            #
            # Create a zip file of the HTML build for offline reading.
            # This gets moved into MEDIA_ROOT for downloading.
            #
            html_build_dir = destdir.child('_build', 'html')
            zipfile_name = 'django-docs-%s-%s.zip' % (release.version, release.lang)
            zipfile_path = Path(settings.MEDIA_ROOT).child('docs', zipfile_name)
            if not zipfile_path.parent.exists():
                zipfile_path.parent.mkdir(parents=True)
            if verbosity >= 2:
                print "  build zip (into %s)" % zipfile_path
            with closing(zipfile.ZipFile(zipfile_path, 'w')) as zf:
                for f in html_build_dir.walk(filter=Path.isfile):
                    zf.write(f, html_build_dir.rel_path_to(f))

            #
            # Rebuild the imported document list and search index.
            #
            if not kwargs['reindex']:
                continue

            if verbosity >= 2:
                print "  reindexing..."

            # Build a dict of {path_fragment: document_object}. We'll pop values
            # out of this dict as we go which'll make sure we know which
            # remaining documents need to be deleted (and unindexed) later on.
            documents = dict((doc.path, doc) for doc in release.documents.all())

            # Walk the tree we've just built looking for ".fjson" documents
            # (just JSON, but Sphinx names them weirdly). Each one of those
            # documents gets a corresponding Document object created which
            # we'll then ask Sphinx to reindex.
            #
            # We have to be a bit careful to reverse-engineer the correct
            # relative path component, especially for "index" documents,
            # otherwise the search results will be incorrect.
            json_build_dir = destdir.child('_build', 'json')
            for built_doc in json_build_dir.walk():
                if built_doc.isfile() and built_doc.ext == '.fjson':

                    # Convert the built_doc path which is now an absolute
                    # path (i.e. "/home/docs/en/1.2/_build/ref/models.json")
                    # into a path component (i.e. "ref/models").
                    path = json_build_dir.rel_path_to(built_doc)
                    if path.stem == 'index':
                        path = path.parent
                    path = str(path.parent.child(path.stem))

                    # Read out the content and create a new Document object for
                    # it. We'll strip the HTML tags here (for want of a better
                    # place to do it).
                    with open(built_doc) as fp:
                        json_doc = json.load(fp)
                        try:
                            json_doc['body']  # Just to make sure it exists.
                            title = strip_tags(json_doc['title'])
                        except KeyError, ex:
                            if verbosity >= 2:
                                print "Skipping: %s (no %s)" % (path, ex.args[0])
                            continue

                    doc = documents.pop(path, Document(path=path, release=release))
                    doc.title = title
                    doc.save()
                    haystack.site.update_object(doc)

            # Clean up any remaining documents.
            for doc in documents.values():
                if verbosity >= 2:
                    print "Deleting:", doc
                haystack.site.remove_object(doc)
                doc.delete()
Ejemplo n.º 8
0
    def handle_noargs(self, **kwargs):
        try:
            verbosity = int(kwargs["verbosity"])
        except (KeyError, TypeError, ValueError):
            verbosity = 1

        # Somehow, bizarely, there's a bug in Sphinx such that if I try to
        # build 1.0 before other versions, things fail in weird ways. However,
        # building newer versions first works. I suspect Sphinx is hanging onto
        # some global state. Anyway, we can work around it by making sure that
        # "dev" builds before "1.0". This is ugly, but oh well.
        for release in DocumentRelease.objects.order_by("-version"):
            if verbosity >= 1:
                print "Updating %s..." % release

            destdir = Path(settings.DOCS_BUILD_ROOT).child(release.lang, release.version)
            if not destdir.exists():
                destdir.mkdir(parents=True)

            #
            # Update the release from SCM.
            #

            # Make an SCM checkout/update into the destination directory.
            # Do this dynamically in case we add other SCM later.
            getattr(self, "update_%s" % release.scm)(release.scm_url, destdir)

            #
            # Use Sphinx to build the release docs into JSON and HTML documents.
            #
            if release.docs_subdir:
                source_dir = destdir.child(*release.docs_subdir.split("/"))
            else:
                source_dir = destdir

            for builder in ("json", "html"):
                # Wipe and re-create the build directory. See #18930.
                build_dir = destdir.child("_build", builder)
                if build_dir.exists():
                    shutil.rmtree(build_dir)
                build_dir.mkdir(parents=True)

                # "Shell out" (not exactly, but basically) to sphinx-build.
                if verbosity >= 2:
                    print "  building %s (%s -> %s)" % (builder, source_dir, build_dir)
                sphinx.cmdline.main(
                    [
                        "sphinx-build",
                        "-b",
                        builder,
                        "-q",  # Be vewy qwiet
                        source_dir,  # Source file directory
                        build_dir,  # Destination directory
                    ]
                )

            #
            # Create a zip file of the HTML build for offline reading.
            # This gets moved into STATIC_ROOT for downloading.
            #
            html_build_dir = destdir.child("_build", "html")
            zipfile_name = "django-docs-%s-%s.zip" % (release.version, release.lang)
            zipfile_path = Path(settings.STATIC_ROOT).child("docs", zipfile_name)
            if not zipfile_path.parent.exists():
                zipfile_path.parent.mkdir(parents=True)
            if verbosity >= 2:
                print "  build zip (into %s)" % zipfile_path

            def zipfile_inclusion_filter(f):
                return f.isfile() and ".doctrees" not in f.components()

            with closing(zipfile.ZipFile(zipfile_path, "w")) as zf:
                for f in html_build_dir.walk(filter=zipfile_inclusion_filter):
                    zf.write(f, html_build_dir.rel_path_to(f))

            #
            # Copy the build results to the directory used for serving
            # the documentation in the least disruptive way possible.
            #
            build_dir = destdir.child("_build")
            built_dir = destdir.child("_built")
            subprocess.check_call(
                ["rsync", "--archive", "--delete", "--link-dest=" + build_dir, build_dir + "/", built_dir]
            )

            #
            # Rebuild the imported document list and search index.
            #
            if not kwargs["reindex"]:
                continue

            if verbosity >= 2:
                print "  reindexing..."

            # Build a dict of {path_fragment: document_object}. We'll pop values
            # out of this dict as we go which'll make sure we know which
            # remaining documents need to be deleted (and unindexed) later on.
            documents = dict((doc.path, doc) for doc in release.documents.all())

            # Walk the tree we've just built looking for ".fjson" documents
            # (just JSON, but Sphinx names them weirdly). Each one of those
            # documents gets a corresponding Document object created which
            # we'll then ask Sphinx to reindex.
            #
            # We have to be a bit careful to reverse-engineer the correct
            # relative path component, especially for "index" documents,
            # otherwise the search results will be incorrect.
            json_built_dir = destdir.child("_built", "json")
            for built_doc in json_built_dir.walk():
                if built_doc.isfile() and built_doc.ext == ".fjson":

                    # Convert the built_doc path which is now an absolute
                    # path (i.e. "/home/docs/en/1.2/_built/ref/models.json")
                    # into a path component (i.e. "ref/models").
                    path = json_built_dir.rel_path_to(built_doc)
                    if path.stem == "index":
                        path = path.parent
                    path = str(path.parent.child(path.stem))

                    # Read out the content and create a new Document object for
                    # it. We'll strip the HTML tags here (for want of a better
                    # place to do it).
                    with open(built_doc) as fp:
                        json_doc = json.load(fp)
                        try:
                            json_doc["body"]  # Just to make sure it exists.
                            title = unescape_entities(strip_tags(json_doc["title"]))
                        except KeyError, ex:
                            if verbosity >= 2:
                                print "Skipping: %s (no %s)" % (path, ex.args[0])
                            continue

                    doc = documents.pop(path, Document(path=path, release=release))
                    doc.title = title
                    doc.save()
                    haystack.site.update_object(doc)

            # Clean up any remaining documents.
            for doc in documents.values():
                if verbosity >= 2:
                    print "Deleting:", doc
                haystack.site.remove_object(doc)
                doc.delete()
Ejemplo n.º 9
0
    def handle_noargs(self, **kwargs):
        try:
            verbosity = int(kwargs['verbosity'])
        except (KeyError, TypeError, ValueError):
            verbosity = 1

        for release in DocumentRelease.objects.all():
            if verbosity >= 1:
                print "Updating %s..." % release

            destdir = Path(settings.DOCS_BUILD_ROOT).child(release.lang, release.version)
            if not destdir.exists():
                destdir.mkdir(parents=True)

            #
            # Update the release from SCM.
            #

            # Make an SCM checkout/update into the destination directory.
            # Do this dynamically in case we add other SCM later.
            getattr(self, 'update_%s' % release.scm)(release.scm_url, destdir)

            #
            # Use Sphinx to build the release docs into JSON and HTML documents.
            #
            for builder in ('json', 'html'):
                # Make the directory for the built files - sphinx-build doesn't
                # do it for us, apparently.
                build_dir = destdir.child('_build', builder)
                if not build_dir.exists():
                    build_dir.mkdir(parents=True)

                # "Shell out" (not exactly, but basically) to sphinx-build.
                if verbosity >= 2:
                    print "  building %s (into %s)" % (builder, build_dir)
                sphinx.cmdline.main(['sphinx-build',
                    '-b', builder,
                    '-q',              # Be vewy qwiet
                    destdir,           # Source file directory
                    build_dir,         # Destination directory
                ])

            #
            # Create a zip file of the HTML build for offline reading.
            # This gets moved into MEDIA_ROOT for downloading.
            #
            html_build_dir = destdir.child('_build', 'html')
            zipfile_name = 'django-docs-%s-%s.zip' % (release.version, release.lang)
            zipfile_path = Path(settings.MEDIA_ROOT).child('docs', zipfile_name)
            if not zipfile_path.parent.exists():
                zipfile_path.parent.mkdir(parents=True)
            if verbosity >= 2:
                print "  build zip (into %s)" % zipfile_path

            def zipfile_inclusion_filter(f):
                return f.isfile() and '.doctrees' not in f.components()

            with closing(zipfile.ZipFile(zipfile_path, 'w')) as zf:
                for f in html_build_dir.walk(filter=zipfile_inclusion_filter):
                    zf.write(f, html_build_dir.rel_path_to(f))

            #
            # Rebuild the imported document list and search index.
            #
            if not kwargs['reindex']:
                continue

            if verbosity >= 2:
                print "  reindexing..."

            # Build a dict of {path_fragment: document_object}. We'll pop values
            # out of this dict as we go which'll make sure we know which
            # remaining documents need to be deleted (and unindexed) later on.
            documents = dict((doc.path, doc) for doc in release.documents.all())

            # Walk the tree we've just built looking for ".fjson" documents
            # (just JSON, but Sphinx names them weirdly). Each one of those
            # documents gets a corresponding Document object created which
            # we'll then ask Sphinx to reindex.
            #
            # We have to be a bit careful to reverse-engineer the correct
            # relative path component, especially for "index" documents,
            # otherwise the search results will be incorrect.
            json_build_dir = destdir.child('_build', 'json')
            for built_doc in json_build_dir.walk():
                if built_doc.isfile() and built_doc.ext == '.fjson':

                    # Convert the built_doc path which is now an absolute
                    # path (i.e. "/home/docs/en/1.2/_build/ref/models.json")
                    # into a path component (i.e. "ref/models").
                    path = json_build_dir.rel_path_to(built_doc)
                    if path.stem == 'index':
                        path = path.parent
                    path = str(path.parent.child(path.stem))

                    # Read out the content and create a new Document object for
                    # it. We'll strip the HTML tags here (for want of a better
                    # place to do it).
                    with open(built_doc) as fp:
                        json_doc = json.load(fp)
                        try:
                            json_doc['body']  # Just to make sure it exists.
                            title = strip_tags(json_doc['title'])
                        except KeyError, ex:
                            if verbosity >= 2:
                                print "Skipping: %s (no %s)" % (path, ex.args[0])
                            continue

                    doc = documents.pop(path, Document(path=path, release=release))
                    doc.title = title
                    doc.save()
                    haystack.site.update_object(doc)

            # Clean up any remaining documents.
            for doc in documents.values():
                if verbosity >= 2:
                    print "Deleting:", doc
                haystack.site.remove_object(doc)
                doc.delete()
Ejemplo n.º 10
0
    def handle_noargs(self, **kwargs):
        try:
            verbosity = int(kwargs["verbosity"])
        except (KeyError, TypeError, ValueError):
            verbosity = 1

        for release in DocumentRelease.objects.all():
            if verbosity >= 1:
                print "Updating %s..." % release

            destdir = Path(settings.DOCS_BUILD_ROOT).child(release.lang, release.version)
            if not destdir.exists():
                destdir.mkdir(parents=True)

            #
            # Update the release from SCM.
            #

            # Make an SCM checkout/update into the destination directory.
            # Do this dynamically in case we add other SCM later.
            getattr(self, "update_%s" % release.scm)(release.scm_url, destdir)

            #
            # Use Sphinx to build the release docs into JSON documents.
            #

            # Make the directory for the JSON files - sphinx-build doesn't
            # do it for us, apparently.
            json_build_dir = destdir.child("_build", "json")
            if not json_build_dir.exists():
                json_build_dir.mkdir(parents=True)

            # "Shell out" (not exactly, but basically) to sphinx-build.
            sphinx.cmdline.main(
                [
                    "sphinx-build",
                    "-b",
                    "json",  # Use the JSON builder
                    "-q",  # Be vewy qwiet
                    destdir,  # Source file directory
                    json_build_dir,  # Destination directory
                ]
            )

            #
            # Rebuild the imported document list and search index.
            #

            # Build a dict of {path_fragment: document_object}. We'll pop values
            # out of this dict as we go which'll make sure we know which
            # remaining documents need to be deleted (and unindexed) later on.
            documents = dict((doc.path, doc) for doc in release.documents.all())

            # Walk the tree we've just built looking for ".fjson" documents
            # (just JSON, but Sphinx names them weirdly). Each one of those
            # documents gets a corresponding Document object created which
            # we'll then ask Sphinx to reindex.
            #
            # We have to be a bit careful to reverse-engineer the correct
            # relative path component, especially for "index" documents,
            # otherwise the search results will be incorrect.
            for built_doc in json_build_dir.walk():
                if built_doc.isfile() and built_doc.ext == ".fjson":

                    # Convert the built_doc path which is now an absolute
                    # path (i.e. "/home/docs/en/1.2/_build/ref/models.json")
                    # into a path component (i.e. "ref/models").
                    path = json_build_dir.rel_path_to(built_doc)
                    if path.stem == "index":
                        path = path.parent
                    path = str(path.parent.child(path.stem))

                    # Read out the content and create a new Document object for
                    # it. We'll strip the HTML tags here (for want of a better
                    # place to do it).
                    with open(built_doc) as fp:
                        json_doc = json.load(fp)
                        try:
                            ignored = json_doc["body"]  # Just to make sure it exists.
                            title = strip_tags(json_doc["title"])
                        except KeyError, ex:
                            if verbosity >= 2:
                                print "Skipping: %s (no %s)" % (path, ex.args[0])
                            continue

                    doc = documents.pop(path, Document(path=path, release=release))
                    doc.title = title
                    if verbosity >= 2:
                        print "Indexing:", doc
                    doc.save()
                    haystack.site.update_object(doc)

            # Clean up any remaining documents.
            for doc in documents.values():
                if verbosity >= 2:
                    print "Deleting:", doc
                haystack.site.remove_object(doc)
                doc.delete()