[damned-lies] Add an admin action to delete a release with related branches (not linked with another release)



commit 7ca9e4f2c8bbfc313eabfe6862ce8489c5c798dd
Author: Claude Paroz <claude 2xlibre net>
Date:   Sat Jan 22 23:37:00 2011 +0100

    Add an admin action to delete a release with related branches (not linked with another release)

 stats/admin.py                                   |   39 +++++++++++++++++++++-
 stats/models.py                                  |   23 ++++++++++--
 templates/admin/delete_release_confirmation.html |   28 +++++++++++++++
 3 files changed, 85 insertions(+), 5 deletions(-)
---
diff --git a/stats/admin.py b/stats/admin.py
index 35a880d..1a2f6a0 100644
--- a/stats/admin.py
+++ b/stats/admin.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2008 Claude Paroz <claude 2xlibre net>.
+# Copyright (c) 2008-2011 Claude Paroz <claude 2xlibre net>.
 #
 # This file is part of Damned Lies.
 #
@@ -19,6 +19,10 @@
 # 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 from django.contrib import admin
+from django.contrib.admin import helpers
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+from django.utils.encoding import force_unicode
 from django import forms
 from stats.models import Statistics, Information, Module, Branch, Domain, Category, Release
 
@@ -75,6 +79,39 @@ class ReleaseAdmin(admin.ModelAdmin):
     list_display = ('name', 'status', 'weight', 'string_frozen')
     list_editable = ('weight',)
     inlines = [ CategoryInline ]
+    actions = ['delete_release']
+
+    def delete_release(self, request, queryset):
+        """ Admin action to delete releases *with* branches which are not linked to another release """
+        if not self.has_delete_permission(request):
+            raise PermissionDenied
+        if request.POST.get('post'):
+            # Already confirmed
+            for obj in queryset:
+                self.log_deletion(request, obj, force_unicode(obj))
+            n = queryset.count()
+            b = 0
+            for release in queryset:
+                branches = Branch.objects.filter(category__release=release)
+                for branch in branches:
+                    if branch.releases.count() < 2 and not branch.is_head():
+                        branch.delete()
+                        b += 1
+            queryset.delete()
+            self.message_user(request, "Successfully deleted %(countr)d release(s) and %(countb)d branch(es)." % {
+                "countr": n, "countb": b,
+            })
+            # Return None to display the change list page again.
+            return None
+        context = {
+            "title": "Are you sure?",
+            "queryset": queryset,
+            "app_label": self.model._meta.app_label,
+            "model_label": self.model._meta.verbose_name_plural,
+            "action_checkbox_name": helpers.ACTION_CHECKBOX_NAME,
+        }
+        return render_to_response('admin/delete_release_confirmation.html', context, context_instance=RequestContext(request))
+    delete_release.short_description = "Delete release (and associated branches)"
 
 class InformationInline(admin.TabularInline):
     model = Information
diff --git a/stats/models.py b/stats/models.py
index 14fbe6d..d7f7a4b 100644
--- a/stats/models.py
+++ b/stats/models.py
@@ -197,11 +197,26 @@ class Branch(models.Model):
             upd_thread.start()
 
     def delete(self):
+        import shutil # os.rmdir cannot delete non-empty dirs
         # Remove the repo checkout
-        localdir = os.path.join(settings.SCRATCHDIR, self.module.vcs_type, self.module.name + "." + self.name)
-        if os.access(localdir, os.W_OK):
-            import shutil # os.rmdir cannot delete non-empty dirs
-            shutil.rmtree(localdir)
+        if self.module.vcs_type in ('cvs', 'svn'):
+            if os.access(self.co_path(), os.W_OK):
+                shutil.rmtree(self.co_path())
+        elif self.module.vcs_type == 'git':
+            if self.is_head():
+                if os.access(self.co_path(), os.W_OK):
+                    shutil.rmtree(self.co_path())
+            else:
+                cmd = "cd \"%(localdir)s\" && git checkout master && git branch -D %(branch)s" % {
+                    'localdir': self.co_path(),
+                    'branch': self.name,
+                }
+                utils.run_shell_command(cmd)
+        #To be implemented for hg/bzr
+
+        # Remove the pot/po generated files
+        if os.access(self.output_dir('ui'), os.W_OK):
+            shutil.rmtree(self.output_dir('ui'))
         super(Branch, self).delete()
 
     def __cmp__(self, other):
diff --git a/templates/admin/delete_release_confirmation.html b/templates/admin/delete_release_confirmation.html
new file mode 100644
index 0000000..b5ca495
--- /dev/null
+++ b/templates/admin/delete_release_confirmation.html
@@ -0,0 +1,28 @@
+{% extends "admin/base_site.html" %}
+{% load i18n %}
+
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+     <a href="../../">{% trans "Home" %}</a> &rsaquo;
+     <a href="../">{{ app_label|capfirst }}</a> &rsaquo;
+     <a href="./">{{ model_label|capfirst }}</a> &rsaquo;
+     Delete multiple objects
+</div>
+{% endblock %}
+
+{% block content %}
+    <p>Are you sure you want to delete the selected release(s)? All branches (and stats) wich are only linked to the release(s) will also be deleted:</p>
+    <ul>{% for obj in queryset %}
+    <li>{{ obj }}</li>
+    {% endfor %}</ul>
+    <form action="" method="post">{% csrf_token %}
+    <div>
+    {% for obj in queryset %}
+    <input type="hidden" name="{{ action_checkbox_name }}" value="{{ obj.pk }}" />
+    {% endfor %}
+    <input type="hidden" name="action" value="delete_release" />
+    <input type="hidden" name="post" value="yes" />
+    <input type="submit" value="Yes, I'm sure" />
+    </div>
+    </form>
+{% endblock %}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]