1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-02 23:48:47 +00:00

add file search

This commit is contained in:
lins05
2013-03-04 17:25:47 +08:00
parent 08e333a9f6
commit c22c31c80a
7 changed files with 240 additions and 5 deletions

View File

@@ -1915,6 +1915,7 @@ textarea:-moz-placeholder {/* for FF */
height: 30px; height: 30px;
} }
/* wiki page */ /* wiki page */
#wiki-area.article { #wiki-area.article {
padding: 0 0; padding: 0 0;
@@ -1925,3 +1926,55 @@ textarea:-moz-placeholder {/* for FF */
.wiki-page-missing { .wiki-page-missing {
color:red; color:red;
} }
#search-form {
float: right;
margin-top: 5px;
width: 200px;
height: 24px;
border: 2px solid #CDCDCD;
border-color: #9A9A9A #CDCDCD #CDCDCD #9A9A9A;
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
box-shadow: 0 0 0 #000,inset 0px 3px 3px #eee;
-moz-box-shadow: 0 0 0 #000,inset 0px 3px 3px #eee;
-webkit-box-shadow: 0 0 0 #000,inset 0px 3px 3px #eee;
}
#search-keyword {
margin: 0;
width: 180px;
height: 20px;
padding: 2px;
padding-left: 18px;
font-size: 12px;
line-height: 12px;
border: 0;
outline: 0;
background: url('../img/search.png') no-repeat scroll left center;
}
.search-info {
font-size: 16px;
border-bottom: 1px solid #8A948F;
padding-bottom: 3px;
}
.search-result-count {
font-size: 13px;
color: #999;
line-height: 35px;
}
.search-info-keyword {
font-size: 18px;
font-weight: bold;
}
.search-results {
margin-top: 10px;
}

BIN
media/img/search.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

58
search.py Normal file
View File

@@ -0,0 +1,58 @@
import settings
import os
import stat
import simplejson as json
import re
import tempfile
import sys
import urllib
import urllib2
import logging
import chardet
from urllib import quote
from django.core.cache import cache
from django.core.urlresolvers import reverse
from django.core.mail import send_mail
from django.contrib import messages
from django.contrib.sites.models import Site, RequestSite
from django.db import IntegrityError
from django.db.models import F
from django.http import HttpResponse, HttpResponseBadRequest, Http404, \
HttpResponseRedirect
from django.shortcuts import render_to_response, redirect
from django.template import Context, loader, RequestContext
from django.template.loader import render_to_string
from django.utils.hashcompat import md5_constructor
from django.utils.translation import ugettext as _
from django.views.generic.base import TemplateView, TemplateResponseMixin
from django.views.generic.edit import BaseFormView, FormMixin
from auth.decorators import login_required
from seahub.utils import search_file_by_name
@login_required
def search(request):
keyword = request.GET['keyword']
current_page = int(request.GET.get('page', '1'))
per_page= int(request.GET.get('per_page', '25'))
start = (current_page - 1) * per_page
size = per_page
results, total = search_file_by_name(request, keyword, start, size)
if total > current_page * per_page:
has_more = True
else:
has_more = False
return render_to_response('search_results.html', {
'keyword': keyword,
'results': results,
'total': total,
'has_more': has_more,
'current_page': current_page,
'prev_page': current_page - 1,
'next_page': current_page + 1,
'per_page': per_page,
}, context_instance=RequestContext(request))

View File

@@ -86,6 +86,12 @@
<img src="{{ MEDIA_URL }}img/logo.png?t=1362454620" title="Seafile" alt="Seafile logo" /> <img src="{{ MEDIA_URL }}img/logo.png?t=1362454620" title="Seafile" alt="Seafile logo" />
</a> </a>
{% block nav %}{% endblock %} {% block nav %}{% endblock %}
{% if request.user.is_authenticated %}
<form id="search-form" method="GET" action="{% url 'search' %}">
<input id="search-keyword" name="keyword" placeholder="{% trans 'Search Seafile' %}" />
</form>
{% endif %}
</div> </div>
</div> </div>
@@ -162,16 +168,16 @@ $('#info-bar .close').click(function() {
info_id_exist = false, info_id_exist = false,
new_info_id = $(this).attr('data') + '_'; new_info_id = $(this).attr('data') + '_';
date.setTime(date.getTime() + 14*24*60*60*1000); date.setTime(date.getTime() + 14*24*60*60*1000);
new_info_id += '; expires=' + date.toGMTString() + '; path=' + '{{ SITE_ROOT }}'; new_info_id += '; expires=' + date.toGMTString() + '; path=' + '{{ SITE_ROOT }}';
for (var i = 0, len = cookies.length; i < len; i++) { for (var i = 0, len = cookies.length; i < len; i++) {
if (cookies[i].split('=')[0] == 'info_id') { if (cookies[i].split('=')[0] == 'info_id') {
info_id_exist = true; info_id_exist = true;
document.cookie = 'info_id=' + cookies[i].split('=')[1] + new_info_id; document.cookie = 'info_id=' + cookies[i].split('=')[1] + new_info_id;
break; break;
} }
} }
if (!info_id_exist) { if (!info_id_exist) {
document.cookie = 'info_id=' + new_info_id; document.cookie = 'info_id=' + new_info_id;
} }
} }
}); });
@@ -197,6 +203,7 @@ $(document).click(function(e) {
$('#account-context').attr('data', 'no-popup'); $('#account-context').attr('data', 'no-popup');
} }
}); });
{% endif %} {% endif %}
{% endif %} {% endif %}
</script> </script>

View File

@@ -0,0 +1,71 @@
{% extends base_template %}
{% load seahub_tags avatar_tags i18n %}
{% load url from future %}
{% block right_panel %}
<p class="search-info">
{% trans 'Search results for' %} <span class="search-info-keyword">"{{ keyword }}"</span>
</p>
{% if not results %}
<p class="search-results-empty">
{% trans 'No search result found' %}
</p>
{% else %}
<p class="search-result-count">{% trans 'Found' %} {{ total }} {% trans 'results' %} </p>
<table class="search-results">
<tr>
<th width="10%"></th> <!-- icon -->
<th width="40%">{% trans 'Name' %}</th>
<th width="30%">{% trans 'Library' %}</th>
<th width="20%">{% trans 'Owner' %}</th>
</tr>
{% 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 }}">{{ file.name }}</a>
({{ file.score }})
</td>
<td>
<a href="{% url 'repo' repo_id=file.repo.id %}">{{ file.repo.name }}</a>
</td>
<td>
{% avatar file.repo.owner 20 %}
<a class="name" href="{% url 'profile.views.user_profile' file.repo.owner %}">{{ file.repo.owner|email2nickname }}</a>
</td>
</tr>
{% endfor %}
</table>
<div id="paginator">
{% if current_page != 1 %}
<a href="?keyword={{ keyword|urlencode }}&page={{ prev_page }}&per_page={{ per_page }}">{% trans "Previous"%}</a>
{% endif %}
{% if has_more %}
<a href="?keyword={{ keyword|urlencode }}&page={{ next_page }}&per_page={{ per_page }}">{% trans "Next"%}</a>
{% endif %}
{% if current_page != 1 or has_more %}
|
{% endif %}
<span>{% trans "Per page: "%}</span>
{% if per_page == 25 %}
<span> 25 </span>
{% else %}
<a href="?keyword={{ keyword|urlencode }}&page={{ current_page }}&per_page=25" class="per-page">25</a>
{% endif %}
{% if per_page == 50 %}
<span> 50 </span>
{% else %}
<a href="?keyword={{ keyword|urlencode }}&page={{ current_page }}&per_page=50" class="per-page">50</a>
{% endif %}
{% if per_page == 100 %}
<span> 100 </span>
{% else %}
<a href="?keyword={{ keyword|urlencode }}&page={{ current_page }}&per_page=100" class="per-page">100</a>
{% endif %}
</div>
{% endif %}
{% endblock %}

View File

@@ -5,6 +5,7 @@ from django.views.generic.simple import direct_to_template
from seahub.views import * from seahub.views import *
from seahub.views.file import view_file, view_history_file, view_trash_file,\ from seahub.views.file import view_file, view_history_file, view_trash_file,\
view_snapshot_file view_snapshot_file
from seahub.search import search
from notifications.views import notification_list from notifications.views import notification_list
from group.views import group_list from group.views import group_list
@@ -101,6 +102,8 @@ urlpatterns = patterns('',
url(r'^sys/useradmin/$', sys_useradmin, name='sys_useradmin'), url(r'^sys/useradmin/$', sys_useradmin, name='sys_useradmin'),
url(r'^sys/orgadmin/$', sys_org_admin, name='sys_org_admin'), url(r'^sys/orgadmin/$', sys_org_admin, name='sys_org_admin'),
url(r'^sys/groupadmin/$', sys_group_admin, name='sys_group_admin'), url(r'^sys/groupadmin/$', sys_group_admin, name='sys_group_admin'),
url(r'^search/$', search, name='search'),
) )
if settings.SERVE_STATIC: if settings.SERVE_STATIC:
@@ -125,4 +128,3 @@ else:
url(r'^pubinfo/groups/$', pubgrp, name='pubgrp'), url(r'^pubinfo/groups/$', pubgrp, name='pubgrp'),
url(r'^pubinfo/users/$', pubuser, name='pubuser'), url(r'^pubinfo/users/$', pubuser, name='pubuser'),
) )

View File

@@ -770,4 +770,48 @@ def is_textual_file(file_type):
else: else:
return False return False
from seafes import es_get_conn, es_search
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
for repo in owned_repos:
repo.owner = request.user.username
for repo in shared_repos:
repo.owner = repo.user
for repo in pub_repo_list:
repo.owner = repo.user
pubrepo_id_map = {}
for repo in pub_repo_list:
# fix pub repo obj attr name mismatch in seafile/lib/repo.vala
repo.id = repo.repo_id
repo.name = repo.repo_name
pubrepo_id_map[repo.id] = repo
# get a list of pure non-pub repos
nonpub_repo_list = []
for repo in owned_repos + shared_repos + groups_repos:
if repo.id not in pubrepo_id_map:
nonpub_repo_list.append(repo)
nonpub_repo_ids = [ repo.id for repo in nonpub_repo_list]
files_found, total = es_search(conn, nonpub_repo_ids, keyword, start, size)
if len(files_found) > 0:
# construt a (id, repo) hash table for fast lookup
repo_id_map = {}
for repo in nonpub_repo_list:
repo_id_map[repo.id] = repo
repo_id_map.update(pubrepo_id_map)
for f in files_found:
f['repo'] = repo_id_map[f['repo_id'].encode('UTF-8')]
return files_found, total