Matthew Marshall avatar Matthew Marshall committed 8297059

Added disk usage statistics.

Comments (0)

Files changed (5)

                 first_name=user.first_name,
                 last_name=user.last_name,
                 email=user.email))
-    return render_to_response('profile.html', dict(form=form),
+    disk_usage = Repo.objects.get_user_disk_usage(user)
+    return render_to_response('profile.html',
+            dict(form=form, disk_usage=disk_usage),
             context_instance=RequestContext(request))
 
 

htdocs/hgfcgi/dispatch.fcgi

 
 import cgitb, sys
 sys.path += ['/home/freehg/lib/python']
+import os
+# hooks need DJANGO_SETTINGS_MODULE set
+os.environ['DJANGO_SETTINGS_MODULE'] = 'freehg.settings'
+
 from mercurial.hgweb.hgwebdir_mod import hgwebdir
 from mercurial.hgweb.request import wsgiapplication
 from fcgi import WSGIServer
+from freehg.repos.models import Repo
+
+def changegroup(ui, repo, hooktype, **args):
+    dbrepo = Repo.objects.get_from_path(repo.path)
+    dbrepo.update_disk_usage()
+    dbrepo.save()
 from django.utils.html import escape, linebreaks, urlize
 
 import os.path
+import subprocess
 import shutil
+import re
 
 from mercurial import hg, ui
 
+path_re = re.compile(settings.REPO_PATH+"/(\w+)/(\w(\w|-|\.)+\w)(/\.hg)?/?$")
+
+class RepoManager(models.Manager):
+    def get_from_path(self, path):
+        """
+        Returns the repository that corrisponds to the given filesystem
+        directory.
+
+        ``path`` may optionally include the ".hg" directory.
+        """
+        if path.endswith("/.hg"):
+            path = path[:-4]
+        match = path_re.match(path)
+        if not match:
+            raise ValueError("Invalid repository path: %r" % path)
+        g = match.groups()
+        return self.get(owner__username=g[0], name=g[1])
+
+    def get_user_disk_usage(self, user):
+        from django.db import connection
+        cursor = connection.cursor()
+        cursor.execute("SELECT sum(r.disk_usage) "
+                "FROM repos_repo AS r JOIN auth_user AS u ON u.id = r.owner_id "
+                "WHERE u.username=%s ", [user.username])
+        return cursor.fetchone()[0]
+
+    def update_all_disk_usage(self):
+        for repo in self.all():
+            repo.update_disk_usage()
+            repo.save()
+
+    def update_all_hgrc(self):
+        for repo in self.all():
+            repo.write_hgrc()
+
 class Repo(models.Model):
     # 'name' is the name used in the url and filesystem.
     name = models.CharField(max_length=30)
 
     creation_date = models.DateTimeField(auto_now_add=True)
 
+    disk_usage = models.IntegerField(blank=True, null=True)
+
+    objects = RepoManager()
+
     class Admin:
         list_display = ("name", "owner")
         search_fields = ("name", "owner__username")
             f.write("description = %s\n" %
                 self.get_html_description().replace('\n','').replace('%', '%%'))
         f.write("contact = %s\n" % (self.owner.get_full_name() or self.owner.username))
+
+        f.write("[hooks]\n")
+        f.write("changegroup = python:freehg.repos.hooks.changegroup\n")
+
         f.close()
 
+    def update_disk_usage(self):
+        assert(os.path.exists(self.file_path+"/.hg"))
+        p = subprocess.Popen(['du','-s',self.file_path], stdout=subprocess.PIPE)
+        if p.wait() != 0:
+            raise RuntimeError("Calling du failed (returned %d.)" %
+                    p.returncode)
+        result = p.stdout.read()
+        match = re.search("^(\d+)", result)
+        if not match:
+            raise ValueError("Could not parse du output: %r" % result)
+        self.disk_usage = int(match.groups()[0])
+
 
     def get_html_description(self):
         return linebreaks(urlize(escape(self.description)))

templates/profile.html

 
 {% if user.repo_set.count %}
 <div class="span-14 clear">
+    <p>You are using <em>{{disk_usage|filesizeformat}}</em> of disk space.</p>
     <table>
     {% for repo in user.repo_set.all %}
         <tr><td><a href="{{repo.get_absolute_url}}">
             {{repo.get_long_name}}
-        </a></td><td><a href="{{repo.get_absolute_url}}edit/">edit</a> | <a href="{{repo.get_absolute_url}}delete/">delete</a></td></tr>
+        </a></td>
+        <td>{{repo.disk_usage|filesizeformat}}</td>
+        <td><a href="{{repo.get_absolute_url}}edit/">edit</a> | <a href="{{repo.get_absolute_url}}delete/">delete</a></td></tr>
     {% endfor %}
     </table>
 </div>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.