1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-03 07:55:36 +00:00

add search results highlight

This commit is contained in:
lins05
2013-03-09 14:15:53 +08:00
parent 2bb4532fb9
commit d4525e2845
7 changed files with 188 additions and 59 deletions

View File

@@ -13,6 +13,11 @@ try:
except ImportError:
BUSINESS_MODE = False
try:
from settings import ENABLE_FILE_SEARCH
except ImportError:
ENABLE_FILE_SEARCH = False
def base(request):
"""
Add seahub base configure to the context.
@@ -37,5 +42,6 @@ def base(request):
'site_name': SITE_NAME,
'enable_signup': ENABLE_SIGNUP,
'max_file_name': MAX_FILE_NAME,
'enable_file_search': ENABLE_FILE_SEARCH,
}

View File

@@ -182,3 +182,16 @@ class DirFilesLastModifiedInfo(models.Model):
class Meta:
unique_together = ('repo_id', 'parent_dir_hash')
class FileLastModifiedInfo(models.Model):
repo_id = models.CharField(max_length=36, db_index=True)
file_id = models.CharField(max_length=40)
file_path = models.TextField()
file_path_hash = models.CharField(max_length=12)
last_modified = models.BigIntegerField()
email = models.EmailField()
class Meta:
unique_together = ('repo_id', 'file_path_hash')

View File

@@ -1971,6 +1971,41 @@ textarea:-moz-placeholder {/* for FF */
background:#f7f7f8;
border-radius:2px;
}
#search-results {
padding-top:15px;
}
#search-results a {
font-weight: normal;
}
#search-results b {
font-weight: bold;
}
.search-results-item {
margin-top: 20px;
clear: left;
}
.search-results-item .file-icon {
display: block;
float: left;
}
.search-results-item .title {
margin: 0 0 0 40px;
}
.search-results-item .title a,
.search-results-item .title img,
.search-results-item .title span
{
vertical-align: middle;
}
.search-results-item .content {
clear: left;
margin: 0 0 0 40px;
}

View File

@@ -87,7 +87,7 @@
</a>
{% block nav %}{% endblock %}
{% if request.user.is_authenticated %}
{% if enable_file_search and request.user.is_authenticated %}
<form id="top-search-form" method="get" action="{% url 'search' %}" class="search-form fright">
<input class="search-input" name="q" placeholder="{% trans 'Search Files' %}" value="{{ keyword }}" />
<input type="submit" value="" class="search-submit" />

View File

@@ -16,26 +16,39 @@
<p>{% trans 'No result found' %}</p>
{% else %}
<p class="tip">{% blocktrans count counter=total %}{{ total }} result{% plural %}{{ total }} results{% endblocktrans%}</p>
<table>
<tr>
<th width="5%"></th>
<th width="45%">{% trans 'Name' %}</th>
<th width="22%">{% trans 'Library' %}</th>
<th width="28%">{% trans 'Owner' %}</th>
</tr>
<ul id="search-results-list">
{% for file in results %}
<tr>
<td><img src="{{ MEDIA_URL }}img/file/{{ file.name|file_icon_filter }}" alt="{% trans "File"%}" /></td>
<td><a href="{% url 'repo_view_file' repo_id=file.repo.id %}?p={{ file.fullpath|urlencode }}" target="_blank">{{ file.name }}</a></td>
<td><a href="{% url 'repo' repo_id=file.repo.id %}" target="_blank">{{ file.repo.name }}</a></td>
<td>
{% avatar file.repo.owner 20 %}
<a class="name" href="{% url 'profile.views.user_profile' file.repo.owner %}" target="_blank">{{ file.repo.owner|email2nickname }}</a>
</td>
</tr>
<li class="search-results-item">
<img class="file-icon" src="{{ MEDIA_URL }}img/file/{{ file.name|file_icon_filter }}" alt="{% trans "File"%}" />
<div class="title">
<a href="{% url 'repo' repo_id=file.repo.id %}" target="_blank">{{ file.repo.name }}</a>
<span></span>
<a class="filename" href="{% url 'repo_view_file' repo_id=file.repo.id %}?p={{ file.fullpath|urlencode }}" target="_blank" title="{{ file.fullpath|slice:'1:'}}" >
{% if file.name_highlight %}
{{ file.name_highlight|safe }}
{% else %}
{{ file.name }}
{% endif %}
</a>
<p>
{% if file.last_modified_by %}
{% avatar file.last_modified_by 20 %}
<a class="name" href="{% url 'profile.views.user_profile' file.last_modified_by %}">{{ file.last_modified_by|email2nickname }}</a>
{% endif %}
{% if file.last_modified %}
{{ file.last_modified|translate_seahub_time }}
{% endif %}
</p>
</div>
{% if file.content_highlight %}
<div class="content">
{{ file.content_highlight|safe }}
</div>
{% endif %}
</li>
{% endfor %}
</table>
{% if total > 25 %}
</ul>
{% if total > per_page %}
<div id="paginator">
{% if current_page != 1 %}
<a href="?q={{ keyword|urlencode }}&page={{ prev_page }}&per_page={{ per_page }}">{% trans "Previous"%}</a>

View File

@@ -103,7 +103,6 @@ urlpatterns = patterns('',
url(r'^sys/orgadmin/$', sys_org_admin, name='sys_org_admin'),
url(r'^sys/groupadmin/$', sys_group_admin, name='sys_group_admin'),
url(r'^search/$', search, name='search'),
)
if settings.SERVE_STATIC:
@@ -128,3 +127,8 @@ else:
url(r'^pubinfo/groups/$', pubgrp, name='pubgrp'),
url(r'^pubinfo/users/$', pubuser, name='pubuser'),
)
if getattr(settings, 'ENABLE_FILE_SEARCH', False):
urlpatterns += patterns('',
url(r'^search/$', search, name='search'),
)

View File

@@ -15,7 +15,7 @@ from django.template import RequestContext
from django.utils.hashcompat import sha_constructor, md5_constructor
from django.utils.translation import ugettext as _
from base.models import FileContributors, UserStarredFiles, DirFilesLastModifiedInfo
from base.models import FileContributors, UserStarredFiles, DirFilesLastModifiedInfo, FileLastModifiedInfo
from htmldiff import HtmlDiff
@@ -406,6 +406,54 @@ def check_and_get_org_by_group(group_id, user):
return org, base_template
def calc_file_last_modified(repo_id, file_path, file_path_hash, file_id):
try:
# get the lastest one file revision
commits = seafserv_threaded_rpc.list_file_revisions(repo_id, file_path, 1, -1)
except SearpcError, e:
return '', 0
if not commits:
return '', 0
email, last_modified = commits[0].creator_name, commits[0].ctime
info = FileLastModifiedInfo(repo_id=repo_id,
file_path=file_path,
file_path_hash=file_path_hash,
file_id=file_id,
last_modified=last_modified,
email=email)
try:
info.save()
except IntegrityError:
pass
return email, last_modified
def get_file_last_modified(repo_id, file_path):
email = ''
last_modified = 0
file_path_hash = calc_file_path_hash(file_path)
file_id = seafserv_threaded_rpc.get_file_id_by_path(repo_id, file_path)
try:
fc = FileLastModifiedInfo.objects.get(repo_id=repo_id,
file_path_hash=file_path_hash)
except FileLastModifiedInfo.DoesNotExist:
# has no cache yet
user, last_modified = calc_file_last_modified(repo_id, file_path, file_path_hash, file_id)
else:
# cache found
if fc.file_id != file_id:
# but cache is outdated
fc.delete()
user, last_modified = calc_file_last_modified(repo_id, file_path, file_path_hash, file_id)
else:
# cache is valid
user, last_modified = fc.email, fc.last_modified
return user, last_modified
def get_file_contributors_from_revisions(repo_id, file_path):
"""Inspect the file history and get a list of users who have modified the
it.
@@ -413,7 +461,7 @@ def get_file_contributors_from_revisions(repo_id, file_path):
"""
commits = []
try:
commits = seafserv_threaded_rpc.list_file_revisions(repo_id, file_path, -1)
commits = seafserv_threaded_rpc.list_file_revisions(repo_id, file_path, -1, -1)
except SearpcError, e:
return [], 0, ''
@@ -770,12 +818,11 @@ def is_textual_file(file_type):
else:
return False
if getattr(settings, 'ENABLE_FILE_SEARCH', False):
from seafes import es_get_conn, es_search
from seafes import es_get_conn, es_search
conn = es_get_conn()
def search_file_by_name(request, keyword, start, size):
conn = es_get_conn()
def search_file_by_name(request, keyword, start, size):
owned_repos, shared_repos, groups_repos, pub_repo_list = get_user_repos(request.user)
# unify the repo.owner property
@@ -812,6 +859,17 @@ def search_file_by_name(request, keyword, start, size):
repo_id_map.update(pubrepo_id_map)
for f in files_found:
f['repo'] = repo_id_map[f['repo_id'].encode('UTF-8')]
repo = repo_id_map.get(f['repo_id'].encode('UTF-8'), None)
if repo:
f['repo'] = repo
f['exists'] = True
f['last_modified_by'], f['last_modified'] = get_file_last_modified(f['repo_id'], f['fullpath'])
else:
f['exists'] = False
files_found = filter(lambda f: f['exists'], files_found)
return files_found, total
else:
def search_file_by_name(*args):
pass