Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create unique directories, not unique filenames in _downloads #2720

Closed
TormodLandet opened this issue Jun 28, 2016 · 7 comments
Closed

Create unique directories, not unique filenames in _downloads #2720

TormodLandet opened this issue Jun 28, 2016 · 7 comments

Comments

@TormodLandet
Copy link
Contributor

We have a similar problem as bug #823 with files such as CMakeLists.txt and Makefile. The reader will get confused when we tell them to download a demo file along with a CMakeLists.txt file and then they get CMakeLists5.txt which is not recognized by the cmake program, so they must remember to rename the file before running the demo.

We do not require as large a change as #823 (which is why I created a new issue), only that the file base names remain unchanged and unique prefix directories are created. A quick and ugly fix is stick this at the end of conf.py, but hotpatching internal Sphinx APIs is not very maintainable in the long run ...

# Hack to support avoid renaming download files with same names
# coming from different directories (CMakeLists.txt, Makefile etc)
from sphinx.util import FilenameUniqDict
from os import path
def add_file(self, docname, newfile):
    if newfile in self:
        self[newfile][0].add(docname)
        return self[newfile][1]
    uniquename = path.basename(newfile)
    i = 0
    while uniquename in self._existing:
        i += 1
        uniquename = path.join('subdir%s' % i, path.basename(newfile))
    self[newfile] = (set([docname]), uniquename)
    self._existing.add(uniquename)
    return uniquename
FilenameUniqDict.add_file = add_file

# Hack to support sub-directories within the download directory
from sphinx.builders.html import StandaloneHTMLBuilder, ensuredir, copyfile
from docutils.utils import relative_path
from sphinx.util.console import brown
def copy_download_files(self):
    def to_relpath(f):
        return relative_path(self.srcdir, f)
    # copy downloadable files
    if self.env.dlfiles:
        ensuredir(path.join(self.outdir, '_downloads'))
        for src in self.status_iterator(self.env.dlfiles,  # self.app.status_iterator in master ...
                                        'copying downloadable files... ',
                                        brown, len(self.env.dlfiles),
                                        stringify_func=to_relpath):
            dest = self.env.dlfiles[src][1]
            subdirs, filename = os.path.split(dest)
            if subdirs:
                ensuredir(path.join(self.outdir, '_downloads', subdirs))
            try:
                copyfile(path.join(self.srcdir, src),
                         path.join(self.outdir, '_downloads', dest))
            except Exception as err:
                self.warn('cannot copy downloadable file %r: %s' %
                          (path.join(self.srcdir, src), err))
StandaloneHTMLBuilder.copy_download_files = copy_download_files

This works-for-me! Would something similar be appreciated as a patch? I guess more builders would need to be changed?

@shibukawa
Copy link
Contributor

shibukawa commented Jul 20, 2016

I think only HTMLBuilder needs this hack. epub/qthelp don't allow download role. Maybe applehelp/htmlhelp don't support too.

@TormodLandet
Copy link
Contributor Author

This is still a problem, but I am seeing some strange interaction with images.

An image which is linked to several times will have the second link show up as "_images/subdir1/image.png", but the image is located in "_images/image.png" and the first ".. image::" directive shows the correct link. These are obviously the same image, so they should not be treated as different with duplicate names. I will take a look to see if I can figure out what is going on.

If I fix this, would a pull request be appreciated? Having this large hack in conf.py for an extended amount of time is not great

@TormodLandet
Copy link
Contributor Author

The following fixed this, but it probably only works on stable, not master due to self.app.status_iterator vs status_iterator

# Hack to support sub-directories within the _images directory
def copy_image_files(self):
    # type: () -> None
    # copy image files
    if self.images:
        ensuredir(path.join(self.outdir, self.imagedir))
        for src in self.app.status_iterator(self.images, 'copying images... ',
                                            brown, len(self.images)):
            dest = self.images[src]
            subdirs, filename = os.path.split(dest)
            if subdirs:
                ensuredir(path.join(self.outdir, self.imagedir, subdirs))
            try:
                copyfile(path.join(self.srcdir, src),
                         path.join(self.outdir, self.imagedir, dest))
            except Exception as err:
                logger.warning('cannot copy image file %r: %s', path.join(self.srcdir, src), err)
StandaloneHTMLBuilder.copy_image_files = copy_image_files

Do you want a pull request?

@shibukawa
Copy link
Contributor

Thank you. Yes, we want to PR. But for master branch.

Your code affects current behavior. So it should be in 1.6. A potential issue is a link URL for the file would be changed. If any other websites link to the file directly, it becomes 404.

So could you rewrite your code based on master branch and put a comment to "Incompatible changes" section in CHANGES file?

TormodLandet added a commit to TormodLandet/sphinx that referenced this issue Mar 15, 2017
All tests pass on my machine except one, "test_texinfo" in the file
"test_build_textinfo.py", which gives error on a line of the generated
SphinxTests.texti containing::

    @enumerate 24

The error is::

   SphinxTests.texi:2141: bad argument to @enumerate

I do not know anything about texinfo, but I guess/hope this is unrelated
and may be due to the version of makeinfo on my machine?
TormodLandet added a commit to TormodLandet/sphinx that referenced this issue Mar 15, 2017
All tests pass on my machine except one, "test_texinfo" in the file
"test_build_textinfo.py", which gives error on a line of the generated
SphinxTests.texti containing:

    @enumerate 24

The error is:

    SphinxTests.texi:2141: bad argument to @enumerate

I do not know anything about texinfo, but I guess/hope this is unrelated
and may be due to the version of makeinfo on my machine?
@TormodLandet
Copy link
Contributor Author

Pull request created. Now, lets see what travis thinks about it ...

@tk0miya tk0miya added this to the 1.6 milestone Mar 18, 2017
@TormodLandet
Copy link
Contributor Author

Is there anything else I should do about this now, or will it be included in the next release? I believe I have answered/fixed all concerns
@shibukawa @tk0miya

@tk0miya tk0miya modified the milestones: 1.7, 1.6 Apr 15, 2017
@tk0miya tk0miya modified the milestones: 1.7, 1.8 Jan 13, 2018
tk0miya added a commit to tk0miya/sphinx that referenced this issue Aug 25, 2018

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
…, duplicate names, and parallel builds
tk0miya added a commit to tk0miya/sphinx that referenced this issue Sep 2, 2018

Verified

This commit was signed with the committer’s verified signature.
stipsan Cody Olsen
…d:``, duplicate names, and parallel builds
tk0miya added a commit to tk0miya/sphinx that referenced this issue Sep 2, 2018
…d:``, duplicate names, and parallel builds
tk0miya added a commit to tk0miya/sphinx that referenced this issue Sep 2, 2018
…d:``, duplicate names, and parallel builds
tk0miya added a commit that referenced this issue Sep 6, 2018
Fix #2720, #4034: Incorrect links with ``:download:``, duplicate names, and parallel builds
@tk0miya
Copy link
Member

tk0miya commented Sep 6, 2018

Fixed by #5377.
Thank you for reporting!

@tk0miya tk0miya closed this as completed Sep 6, 2018
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants