-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Store ePubs and PDFs in media storage #4947
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
Changes from 11 commits
8f9576d
130bc2e
7a2216e
302b3fd
c3fa90e
b500528
8a602c8
6edacad
03787f4
a7db138
4fab169
9ac1e53
5e9597a
440567a
9ca62db
f97833b
8c14af7
34306ad
76456ab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
import requests | ||
from celery.exceptions import SoftTimeLimitExceeded | ||
from django.conf import settings | ||
from django.core.files.storage import get_storage_class | ||
from django.db.models import Q | ||
from django.urls import reverse | ||
from django.utils import timezone | ||
|
@@ -79,6 +80,7 @@ | |
|
||
|
||
log = logging.getLogger(__name__) | ||
storage = get_storage_class()() | ||
|
||
|
||
class SyncRepositoryMixin: | ||
|
@@ -703,6 +705,7 @@ def update_app_instances( | |
search=False, | ||
pdf=False, | ||
epub=False, | ||
delete=True, | ||
): | ||
""" | ||
Update application instances with build artifacts. | ||
|
@@ -722,6 +725,25 @@ def update_app_instances( | |
'Updating version failed, skipping file sync: version=%s', | ||
self.version, | ||
) | ||
hostname = socket.gethostname() | ||
|
||
if getattr(storage, 'write_build_media', False): | ||
# Handle the case where we want to upload some built assets to our storage | ||
move_files.delay( | ||
self.version.pk, | ||
hostname, | ||
self.config.doctype, | ||
html=False, | ||
search=False, | ||
localmedia=localmedia, | ||
pdf=pdf, | ||
epub=epub, | ||
) | ||
# Set variables so they don't get synced in the next broadcast step | ||
localmedia = False | ||
pdf = False | ||
epub = False | ||
delete = False | ||
|
||
# Broadcast finalization steps to web application instances | ||
broadcast( | ||
|
@@ -733,17 +755,17 @@ def update_app_instances( | |
self.config.doctype, | ||
], | ||
kwargs=dict( | ||
hostname=socket.gethostname(), | ||
hostname=hostname, | ||
html=html, | ||
localmedia=localmedia, | ||
search=search, | ||
pdf=pdf, | ||
epub=epub, | ||
delete=delete, | ||
), | ||
callback=sync_callback.s( | ||
version_pk=self.version.pk, | ||
commit=self.build['commit'], | ||
search=search, | ||
), | ||
) | ||
|
||
|
@@ -896,6 +918,7 @@ def sync_files( | |
search=False, | ||
pdf=False, | ||
epub=False, | ||
delete=False, | ||
): | ||
""" | ||
Sync build artifacts to application instances. | ||
|
@@ -907,20 +930,41 @@ def sync_files( | |
version = Version.objects.get_object_or_log(pk=version_pk) | ||
if not version: | ||
return | ||
if not pdf: | ||
remove_dirs([ | ||
version.project.get_production_media_path( | ||
type_='pdf', | ||
version_slug=version.slug, | ||
), | ||
]) | ||
if not epub: | ||
remove_dirs([ | ||
version.project.get_production_media_path( | ||
type_='epub', | ||
version_slug=version.slug, | ||
), | ||
]) | ||
if delete: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there's an issue around this. While I was testing the removal feature, this flag was always There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should only be true when being called w/ the broadcast. I guess we could delete the old ones before replacing them with the new ones, but that seems like wasted effort, but arguably could be done. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For storage, you have to do this. There isn't an "overwrite" option. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Is the implication here that this won't happen when run locally? I wasn't able to successfully test deleting artifacts when PDF/Epubs are disabled locally. Edit: I tested it, but it didn't work correctly. |
||
if not pdf: | ||
remove_dirs([ | ||
version.project.get_production_media_path( | ||
type_='pdf', | ||
version_slug=version.slug, | ||
), | ||
]) | ||
|
||
if getattr(storage, 'write_build_media', False): | ||
# Remove PDF from remote storage if it exists | ||
storage_path = version.project.get_storage_path( | ||
type_='pdf', | ||
version_slug=version.slug, | ||
) | ||
if storage.exists(storage_path): | ||
log.info('Removing %s from media storage', storage_path) | ||
storage.delete(storage_path) | ||
if not epub: | ||
remove_dirs([ | ||
version.project.get_production_media_path( | ||
type_='epub', | ||
version_slug=version.slug, | ||
), | ||
]) | ||
|
||
if getattr(storage, 'write_build_media', False): | ||
# Remove ePub from remote storage if it exists | ||
storage_path = version.project.get_storage_path( | ||
type_='epub', | ||
version_slug=version.slug, | ||
) | ||
if storage.exists(storage_path): | ||
log.info('Removing %s from media storage', storage_path) | ||
storage.delete(storage_path) | ||
|
||
# Sync files to the web servers | ||
move_files( | ||
|
@@ -1000,40 +1044,48 @@ def move_files( | |
Syncer.copy(from_path, to_path, host=hostname) | ||
|
||
if localmedia: | ||
from_path = version.project.artifact_path( | ||
version=version.slug, | ||
type_='sphinx_localmedia', | ||
from_path = os.path.join( | ||
version.project.artifact_path( | ||
version=version.slug, | ||
type_='sphinx_localmedia', | ||
), | ||
'{}.zip'.format(version.project.slug), | ||
) | ||
to_path = version.project.get_production_media_path( | ||
type_='htmlzip', | ||
version_slug=version.slug, | ||
include_file=False, | ||
include_file=True, | ||
) | ||
Syncer.copy(from_path, to_path, host=hostname) | ||
|
||
Syncer.copy(from_path, to_path, host=hostname, is_file=True) | ||
# Always move PDF's because the return code lies. | ||
if pdf: | ||
from_path = version.project.artifact_path( | ||
version=version.slug, | ||
type_='sphinx_pdf', | ||
from_path = os.path.join( | ||
version.project.artifact_path( | ||
version=version.slug, | ||
type_='sphinx_pdf', | ||
), | ||
'{}.pdf'.format(version.project.slug), | ||
) | ||
to_path = version.project.get_production_media_path( | ||
type_='pdf', | ||
version_slug=version.slug, | ||
include_file=False, | ||
include_file=True, | ||
) | ||
Syncer.copy(from_path, to_path, host=hostname) | ||
Syncer.copy(from_path, to_path, host=hostname, is_file=True) | ||
if epub: | ||
from_path = version.project.artifact_path( | ||
version=version.slug, | ||
type_='sphinx_epub', | ||
from_path = os.path.join( | ||
version.project.artifact_path( | ||
version=version.slug, | ||
type_='sphinx_epub', | ||
), | ||
'{}.epub'.format(version.project.slug), | ||
) | ||
to_path = version.project.get_production_media_path( | ||
type_='epub', | ||
version_slug=version.slug, | ||
include_file=False, | ||
include_file=True, | ||
) | ||
Syncer.copy(from_path, to_path, host=hostname) | ||
Syncer.copy(from_path, to_path, host=hostname, is_file=True) | ||
|
||
|
||
@app.task(queue='web') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we strictly talking filesystem path here, or URL path, or both? If filesystem, this should use
os.path.join()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a storage check, not a filesystem check.