1
0
Fork 0
mirror of https://github.com/correl/codereview.git synced 2025-04-13 01:01:01 -09:00

Merge branch 'feature/search' into develop

This commit is contained in:
Correl Roush 2011-01-06 21:59:27 -05:00
commit f7aa1b5bf2
17 changed files with 283 additions and 0 deletions

View file

View file

@ -0,0 +1,24 @@
import sys
from django.core.management.base import BaseCommand, CommandError
from codereview.dashboard.models import Repository
class Command(BaseCommand):
args = '<repositoryname repositoryname ...>'
help = 'Updates commit information in the database required for searching'
def handle(self, *args, **options):
repos = []
if len(args):
# Loop through the arguments to get the repos to update
for arg in args:
try:
repo = Repository.objects.get(name=arg)
if repo not in repos:
repos.append(repo)
except:
print >> sys.stderr, "Unknown repository '%s'" % arg
else:
repos = Repository.objects.all()
for repo in repos:
print 'Updating repo', repo
repo.update()

View file

@ -1,4 +1,6 @@
from collections import deque
from django.db import models
from codereview.browser import vcs
class Repository(models.Model):
name = models.CharField(max_length=200, unique=True)
@ -10,5 +12,76 @@ class Repository(models.Model):
("browse", "Browse repositories"),
)
def update(self):
repo = vcs.create(self.type, self.path)
branches = repo.branches()
for branch, commit in branches.iteritems():
print 'Updating', branch
try:
head = Head.objects.get(repository=self, name=branch)
except:
head = Head(repository=self, name=branch)
try:
c = Commit.objects.get(repository=self, ref=commit.id)
except:
c = Commit(repository=self, ref=commit.id)
c.load(repo)
head.commit = c
head.save()
def __unicode__(self):
return self.name
class Commit(models.Model):
ref = models.CharField(max_length=40)
repository = models.ForeignKey(Repository)
message = models.TextField()
author = models.CharField(max_length=255)
author_email = models.CharField(max_length=255)
committer = models.CharField(max_length=255)
committer_email = models.CharField(max_length=255)
authored_date = models.DateTimeField()
committed_date = models.DateTimeField()
parents = models.ManyToManyField('self')
def load(self, repo):
queue = deque([self])
while queue:
c = queue.popleft()
commit = repo.commit(c.ref)
c.message = commit.message
c.author = commit.author
c.author_email = commit.author_email
c.committer = commit.committer
c.committer_email = commit.committer_email
c.authored_date = commit.authored_date
c.committed_date = commit.committed_date
c.save()
print 'Loading', c.ref
for parent in commit.parents:
try:
p = Commit.objects.get(ref=parent, repository=c.repository)
except:
p = Commit(ref=parent, repository=c.repository)
parent = repo.commit(parent)
p.message = parent.message
p.author = parent.author
p.author_email = parent.author_email
p.committer = parent.committer
p.committer_email = parent.committer_email
p.authored_date = parent.authored_date
p.committed_date = parent.committed_date
p.save()
queue.append(p)
print 'Queuing', p.ref
c.parents.add(p)
c.save()
def __unicode__(self):
return self.ref
class Head(models.Model):
repository = models.ForeignKey(Repository)
commit = models.ForeignKey(Commit)
name = models.CharField(max_length=255)
def __unicode__(self):
return self.name

View file

@ -0,0 +1,8 @@
from haystack.indexes import *
from haystack import site
from codereview.dashboard.models import Commit
class CommitIndex(SearchIndex):
text = CharField(document=True, use_template=True)
site.register(Commit, CommitIndex)

View file

@ -5,6 +5,9 @@ body, th, td {
a {
color: black;
}
.searchbar {
float: right;
}
div.navigation {
width: 300px;
float: left;
@ -122,3 +125,22 @@ table.diff tr.annotation td {
.comment .text {
padding-left: 1em;
}
.searchresult {
border: 1px solid black;
margin-bottom: 1em;
border-radius: .5em;
background-color: #ddd;
}
.searchresult .header,
.searchresult .preview,
.searchresult .footer {
padding: .5em;
}
.searchresult .header {
font-weight: bold;
}
.searchresult .preview {
padding: 1em;
background-color: #eee;
}

8
review/search_indexes.py Normal file
View file

@ -0,0 +1,8 @@
from haystack.indexes import *
from haystack import site
from codereview.review.models import Review
class ReviewIndex(SearchIndex):
text = CharField(document=True, use_template=True)
site.register(Review, ReviewIndex)

2
search_sites.py Normal file
View file

@ -0,0 +1,2 @@
import haystack
haystack.autodiscover()

View file

@ -84,6 +84,9 @@ AUTHENTICATION_BACKENDS = (
'codereview.dashboard.auth.PAMBackend',
)
HAYSTACK_SITECONF = 'codereview.search_sites'
HAYSTACK_SEARCH_ENGINE = 'simple'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
@ -100,6 +103,8 @@ INSTALLED_APPS = (
# Uncomment the next line to enable the admin:
'django.contrib.admin',
'haystack',
'codereview.dashboard',
'codereview.browser',
'codereview.review',

View file

@ -29,6 +29,11 @@
{{ user }}
<a href="{% url django.contrib.auth.views.logout %}">Log Out</a>
<form class="searchbar" method="get" action="/search/">
<label>Search</label>
<input type="text" name="q" />
<input type="submit" value="Go" />
</form>
{% endif %}
</div>
<div class="navigation">
@ -36,6 +41,7 @@
{% endblock %}
</div>
<div class="content">
</form>
{% block content %}
This space intentionally left blank.
{% endblock %}

View file

@ -0,0 +1,32 @@
{% extends 'search/includes/layout.html' %}
{% load gravatar %}
{% load vcs %}
{% block url %}
{% url codereview.browser.views.commit repository=result.object.repository.name ref=result.object.ref %}
{% endblock %}
{% block type %}
Commit
{% endblock %}
{% block title %}
{{ result.object.ref }} -
{{ result.object.message|oneline|truncatewords:10 }}</a>
{% endblock %}
{% block preview %}
<dl>
<dt>Author</dt>
<dd>
<img src="{{ result.object.author_email|gravatar:16 }}" />
{{ result.object.author }}
</dd>
<dt>Committer</dt>
<dd>
<img src="{{ result.object.committer_email|gravatar:16 }}" />
{{ result.object.committer}}
</dd>
</dl>
<hr />
<div class="message">{{ result.object.message|linebreaks }}</div>
{% endblock %}

View file

@ -0,0 +1,21 @@
<div class="searchresult">
<div class="header">
<span class="type">
{% block type %}
Unknown Object
{% endblock %}
:
</span>
<span class="title">
{% block title %}
{% endblock %}
</span>
</div>
<div class="preview">
{% block preview %}
{% endblock %}
</div>
<div class="footer">
<a href="{% block url %}{% endblock %}">View</a>
</div>
</div>

View file

@ -0,0 +1,28 @@
{% extends 'search/includes/layout.html' %}
{% block url %}
{% url codereview.review.views.edit review_id=result.object.id %}
{% endblock %}
{% block type %}
Review
{% endblock %}
{% block title %}
#{{ result.object.id }} -
{{ result.object.description|truncatewords:10 }}</a>
{% endblock %}
{% block preview %}
<dl>
<dt>Commit</dt>
<dd>{{ result.object.ref }}</dd>
<dt>Parent</dt>
<dd>{{ result.object.parent }}</dd>
</dl>
<hr />
<p>
{{ result.object.description|linebreaksbr }}
</p>
{{ result.object.comment_set.count }} Comment(s)
{% endblock %}

View file

@ -0,0 +1,3 @@
{{ object.author }}
{{ object.committer }}
{{ object.message }}

View file

@ -0,0 +1,12 @@
{{ object.author }}
{{ object.description }}
{{ object.ref }} {{ object.parent }}
{% for comment in object.comment_set.all %}
{{ comment.author }}
{{ comment.text }}
{% for response in comment.response_set.all %}
{{ response.author }}
{{ response.text }}
{% endfor %}
{% endfor %}

View file

@ -0,0 +1,37 @@
{% extends 'layouts/default.html' %}
{% block content %}
<h2>Search</h2>
<form method="get" action=".">
<table>
{{ form.as_table }}
<tr>
<td>&nbsp;</td>
<td><input type="submit" value="Search" /></td>
</tr>
</table>
{% if query %}
<h3>Results</h3>
{% for result in page.object_list %}
{% if result.content_type == 'dashboard.commit' %}
{% include 'search/includes/dashboard/commit.html' %}
{% endif %}
{% if result.content_type == 'review.review' %}
{% include 'search/includes/review/review.html' %}
{% endif %}
{% empty %}
<p>No results found.</p>
{% endfor %}
{% if page.has_previous or page.has_next %}
<div>
{% if page.has_previous %}<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; Previous{% if page.has_previous %}</a>{% endif %}
|
{% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}Next &raquo;{% if page.has_next %}</a>{% endif %}
</div>
{% endif %}
{% else %}
{# Show some example queries to run, maybe query syntax, something else? #}
{% endif %}
</form>
{% endblock %}

View file

@ -13,6 +13,8 @@ urlpatterns = patterns('',
(r'^dashboard/', include('codereview.dashboard.urls')),
(r'^review/', include('codereview.review.urls')),
(r'^search/', include('haystack.urls')),
# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
# to INSTALLED_APPS to enable admin documentation:
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),