diff --git a/readthedocs/builds/models.py b/readthedocs/builds/models.py index 57eccf1b7ca..35e5054f788 100644 --- a/readthedocs/builds/models.py +++ b/readthedocs/builds/models.py @@ -159,6 +159,12 @@ def save(self, *args, **kwargs): self.project.sync_supported_versions() return obj + def delete(self, *args, **kwargs): + from readthedocs.projects.tasks import clear_artifacts + log.info('Removing files for version %s' % self.slug) + clear_artifacts.delay(version_pk=self.pk) + super(Version, self).delete(*args, **kwargs) + @property def identifier_friendly(self): '''Return display friendly identifier''' diff --git a/readthedocs/projects/views/private.py b/readthedocs/projects/views/private.py index b6d30653f5b..4f41abb98a7 100644 --- a/readthedocs/projects/views/private.py +++ b/readthedocs/projects/views/private.py @@ -6,6 +6,7 @@ from django.contrib.auth.models import User from django.contrib import messages from django.core.urlresolvers import reverse +from django.conf import settings from django.http import (HttpResponseRedirect, HttpResponseNotAllowed, Http404, HttpResponseBadRequest) from django.db.models import Q @@ -35,7 +36,7 @@ from readthedocs.projects.models import Project, EmailHook, WebHook, Domain from readthedocs.projects.views.base import ProjectAdminMixin from readthedocs.projects import constants, tasks -from readthedocs.projects.tasks import remove_path_from_web +from readthedocs.projects.tasks import remove_dir, clear_artifacts from readthedocs.projects.signals import project_import @@ -198,7 +199,13 @@ def project_version_detail(request, project_slug, version_slug): form = VersionForm(request.POST or None, instance=version) if request.method == 'POST' and form.is_valid(): - form.save() + version = form.save() + if form.has_changed(): + if 'active' in form.changed_data and version.active is False: + log.info('Removing files for version %s' % version.slug) + clear_artifacts.delay(version_pk=version.pk) + version.built = False + version.save() url = reverse('project_version_list', args=[project.slug]) return HttpResponseRedirect(url) @@ -220,8 +227,14 @@ def project_delete(request, project_slug): slug=project_slug) if request.method == 'POST': - # Remove the repository checkout - remove_path_from_web.delay(path=project.doc_path) + # Support hacky "broadcast" with MULTIPLE_APP_SERVERS setting, + # otherwise put in normal celery queue + for server in getattr(settings, "MULTIPLE_APP_SERVERS", ['celery']): + log.info('Removing files on %s' % server) + remove_dir.apply_async( + args=[project.doc_path], + queue=server, + ) # Delete the project and everything related to it project.delete() diff --git a/readthedocs/rtd_tests/tests/test_project_views.py b/readthedocs/rtd_tests/tests/test_project_views.py index 639c70f6496..c871b16aa35 100644 --- a/readthedocs/rtd_tests/tests/test_project_views.py +++ b/readthedocs/rtd_tests/tests/test_project_views.py @@ -212,12 +212,11 @@ def test_delete_project(self): response = self.client.get('/dashboard/pip/delete/') self.assertEqual(response.status_code, 200) - patcher = patch( - 'readthedocs.projects.views.private.remove_path_from_web') - with patcher as remove_path_from_web: + patcher = patch('readthedocs.projects.views.private.remove_dir') + with patcher as remove_dir: response = self.client.post('/dashboard/pip/delete/') self.assertEqual(response.status_code, 302) - self.assertFalse(Project.objects.filter(slug='pip').exists()) - remove_path_from_web.delay.assert_called_with( - path=project.doc_path) + remove_dir.apply_async.assert_called_with( + queue='celery', + args=[project.doc_path])