Source

freehg / repos / models.py

Matthew Marshall 66c0113 
Matthew Marshall 98330b1 


Matthew Marshall aae0f40 
Matthew Marshall 66c0113 
Matthew Marshall 98330b1 
Matthew Marshall 8297059 
Matthew Marshall 98330b1 
Matthew Marshall 8297059 
Matthew Marshall 98330b1 


Matthew Marshall 8297059 


































Matthew Marshall 98330b1 










Matthew Marshall 6dc0841 

Matthew Marshall 8297059 



Matthew Marshall 98330b1 















Matthew Marshall 6dc0841 
Matthew Marshall 98330b1 













Matthew Marshall 4891c62 

Matthew Marshall 98330b1 


Matthew Marshall aae0f40 
Matthew Marshall 4891c62 
Matthew Marshall aae0f40 
Matthew Marshall 4891c62 
Matthew Marshall aae0f40 
Matthew Marshall 4891c62 
Matthew Marshall ce8229a 
Matthew Marshall 4891c62 
Matthew Marshall 8297059 



Matthew Marshall 98330b1 

Matthew Marshall 8297059 

Matthew Marshall b307239 
Matthew Marshall 8297059 








mmar...@swallow 287584c 
Matthew Marshall ce8229a 











Matthew Marshall 98330b1 













from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
from django.dispatch import dispatcher
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)

    long_name = models.CharField(max_length=50, blank=True)
    description = models.TextField(max_length=5000, blank=True)

    owner = models.ForeignKey(User)
    allow_push = models.ManyToManyField(User, related_name="allow_push_set",
            blank=True)

    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")

    class Meta:
        unique_together = (("name", "owner"),)

    @property
    def file_path(self):
        return settings.REPO_PATH+'/'+self.owner.username+"/"+self.name

    @property
    def hgrc_filename(self):
        return self.file_path + "/.hg/hgrc"

    def get_absolute_url(self):
        return "/u/%s/%s/" % (self.owner.username, self.name)

    @property
    def manage_url(self):
        return "/repos/manage/%s/%s/" % (self.owner.username, self.name)

    def __str__(self):
        return "%s/%s" % (self.owner.username, self.name)

    def __repr__(self):
        return "<Repo %s %s>" % (self.owner.username, self.name)

    def write_hgrc(self):
        assert(os.path.exists(self.file_path+"/.hg"))
        f = open(self.hgrc_filename, 'w')
        def wl(line):
            f.write(line.encode('utf8') + "\n")
        f.write("[web]\n")
        f.write("push_ssl = false\n")
        f.write("allow_push = %s\n" % self.owner.username)
        if self.long_name:
            wl("name = %s" % escape(self.get_long_name()))
        else:
            wl("name = %s" % self.name)
        if self.description:
            wl(u"description = %s" %
                self.get_html_description().replace('\n','').replace('%', '%%'))
        wl(u"contact = %s" % escape(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','-b',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)))

    def get_long_name(self):
        if self.long_name:
            return self.long_name
        else:
            return self.name

    def __unicode__(self):
        return self.name

def save_repo(instance):
    repo = instance
    if not os.path.exists(repo.file_path):
        os.makedirs(repo.file_path)
        hg.repository(ui.ui(), repo.file_path, create=True)
    repo.write_hgrc()
    return True
dispatcher.connect(save_repo, signal=models.signals.post_save, sender=Repo)

def delete_repo(instance):
    repo = instance
    if os.path.exists(repo.file_path):
        shutil.rmtree(repo.file_path)
        return True
dispatcher.connect(delete_repo, signal=models.signals.post_delete, sender=Repo)
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.