зеркало из https://github.com/mozilla/FlightDeck.git
Merge branch 'search' into bug-625954-search_frontend
Conflicts: apps/search/urls.py apps/search/utils.py apps/search/views.py urls.py
This commit is contained in:
Коммит
1bb2a1f6a0
|
@ -1,6 +1,6 @@
|
|||
<div id="search-bar">
|
||||
<div class="UI_middleWrapper">
|
||||
<form id="Search" method="get" action="{% url search_results %}">
|
||||
<form id="Search" method="get" action="{% url search.results %}">
|
||||
<fieldset>
|
||||
<label>
|
||||
<span>Search for</span>
|
||||
|
@ -10,4 +10,4 @@
|
|||
<button type="submit">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="/media/jetpack/css/UI.Browser.css" />
|
||||
<link rel="stylesheet" href="/media/search/css/Search.css" />
|
||||
{% endblock %}
|
||||
{% block app_body %}
|
||||
{% include "_search_form.html" %}
|
||||
{% endblock %}
|
||||
{% block app_sidebar %}
|
||||
{% include "search_filter.html" %}
|
||||
{% endblock %}
|
||||
{% block app_content %}
|
||||
<section id="SearchResults">
|
||||
{% if addons %}
|
||||
<h2 class="UI_Heading">Addon Results ({{ addon_total }})</h2>
|
||||
{% for package in addons %}
|
||||
{% include "_package_result.html" %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if libraries %}
|
||||
<h2 class="UI_Heading">Library Results ({{ library_total }})</h2>
|
||||
{% for package in libraries %}
|
||||
{% include "_package_result.html" %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endblock %}
|
|
@ -0,0 +1,29 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="/media/jetpack/css/UI.Browser.css"
|
||||
type="text/css" />
|
||||
<link rel="stylesheet" type="text/css" href="/media/search/css/Search.css" />
|
||||
{% endblock %}
|
||||
{% block app_body %}
|
||||
{% include "_search_form.html" %}
|
||||
{% endblock %}
|
||||
{% block app_sidebar %}
|
||||
{% include "search_filter.html" %}
|
||||
{% endblock %}
|
||||
{% block app_content %}
|
||||
<section id="SearchResults">
|
||||
{% if addons %}
|
||||
<h2 class="UI_Heading">Addon Results ({{ addon_total }})</h2>
|
||||
{% for package in addons %}
|
||||
{% include "_package_result.html" %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if libraries %}
|
||||
<h2 class="UI_Heading">Library Results ({{ library_total }})</h2>
|
||||
{% for package in libraries %}
|
||||
{% include "_package_result.html" %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endblock %}
|
|
@ -1,25 +1,23 @@
|
|||
<h2 class="UI_Heading">Narrow Search</h2>
|
||||
<ul class="UI_Action_List">
|
||||
<li>
|
||||
<a href="#">Combined</a>
|
||||
<strong>({{ addons.count|add:libraries.count }})</strong>
|
||||
<a href="{% url search.results %}?q={{ q }}">Combined</a>
|
||||
<strong>({{ total }})</strong>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">Addons</a>
|
||||
<strong>({{ addons.count }})</strong>
|
||||
<a href="{% url search 'addon' %}?q={{ q }}">Addons</a>
|
||||
<strong>({{ addon_total }})</strong>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">Libraries</a>
|
||||
<strong>({{ libraries.count }})</strong>
|
||||
<a href="{% url search 'library' %}?q={{ q }}">Libraries</a>
|
||||
<strong>({{ library_total }})</strong>
|
||||
</li>
|
||||
</ul>
|
||||
{% if user.is_authenticated %}
|
||||
<ul class="UI_Action_List">
|
||||
<li>
|
||||
<a href="#">By Everyone</a>
|
||||
<strong>(0)</strong>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">By Me</a>
|
||||
<strong>(0)</strong>
|
||||
<a href="{% url search.me %}?q={{ q }}">By Me</a>
|
||||
<strong>({{ my_total }})</strong>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
from django.conf.urls.defaults import url, patterns
|
||||
|
||||
urlpatterns = patterns('search.views',
|
||||
url(r'^$', 'results', name='search_results')
|
||||
url(r'^$', 'results', name='search.results'),
|
||||
url(r'^(?P<type_>addon|library)/$', 'search', name='search'),
|
||||
url(r'^me/$', 'me', name='search.me'),
|
||||
)
|
||||
|
|
|
@ -1,21 +1,93 @@
|
|||
from django.shortcuts import render_to_response
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.shortcuts import render_to_response, redirect
|
||||
from django.template import RequestContext
|
||||
from django.db.models import Q
|
||||
|
||||
from elasticutils import get_es
|
||||
|
||||
from jetpack.models import Package
|
||||
|
||||
def results(r):
|
||||
search_term = r.GET.get('q', '')
|
||||
addons = []
|
||||
libraries = []
|
||||
if search_term:
|
||||
results = Package.objects.filter(Q(name__icontains=search_term) | Q(description__icontains=search_term))
|
||||
addons = results.filter(type='a')
|
||||
libraries = results.filter(type='l')
|
||||
|
||||
def render(request, template, data={}):
|
||||
return render_to_response(template, data, RequestContext(request))
|
||||
|
||||
|
||||
return render_to_response('results.html', {
|
||||
'addons': addons,
|
||||
'libraries': libraries,
|
||||
'q': search_term,
|
||||
}, context_instance=RequestContext(r))
|
||||
def _get_facets(results):
|
||||
facets = results['facets']
|
||||
type_facets = dict(((z['term'], z['count']) for z in
|
||||
facets['type']['terms']))
|
||||
return type_facets.get('addon', 0), type_facets.get('library', 0)
|
||||
|
||||
|
||||
def _get_packages(results):
|
||||
hits = results['hits']
|
||||
results = {}
|
||||
for type_ in ('a', 'l'):
|
||||
ids = [r['_source']['id'] for r in hits['hits']
|
||||
if r['_source']['type'] == type_]
|
||||
results[type_] = Package.objects.filter(pk__in=ids)
|
||||
return results['a'], results['l']
|
||||
|
||||
|
||||
term_facet = lambda f: {'terms': dict(field=f, size=10)}
|
||||
|
||||
|
||||
def _query(searchq, type_=None, user=None, filter_by_user=False):
|
||||
if searchq:
|
||||
es = get_es()
|
||||
facets = dict(type=term_facet('_type'))
|
||||
if user and user.is_authenticated():
|
||||
facet = term_facet('author')
|
||||
facet['terms']['script'] = 'term == %d ? true : false' % user.id
|
||||
facets['author'] = facet
|
||||
|
||||
query = dict(query=dict(query_string=dict(query=searchq)),
|
||||
facets=facets)
|
||||
|
||||
if type_ in ('addon', 'library'):
|
||||
query['filter'] = {'term': {'_type': type_}}
|
||||
|
||||
# Can filter by user or type, not both.
|
||||
if filter_by_user:
|
||||
query['filter'] = {'term': {'author': user.id}}
|
||||
|
||||
r = es.search(query, 'flightdeck')
|
||||
addon_total, library_total = _get_facets(r)
|
||||
addons, libraries = _get_packages(r)
|
||||
|
||||
data = dict(addon_total=addon_total, library_total=library_total,
|
||||
addons=addons, libraries=libraries,
|
||||
total=r['hits']['total'], q=searchq)
|
||||
|
||||
if user and user.is_authenticated():
|
||||
data['my_total'] = 0
|
||||
facets = r['facets']['author']['terms']
|
||||
if facets:
|
||||
data['my_total'] = facets[0]['count']
|
||||
|
||||
else:
|
||||
data = {}
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def results(request):
|
||||
"""This aggregates the first results from add-ons and libraries."""
|
||||
q = request.GET.get('q')
|
||||
data = _query(q, user=request.user)
|
||||
return render(request, 'search/results.html', data)
|
||||
|
||||
|
||||
def search(request, type_):
|
||||
"""This is a search into either addons or libraries."""
|
||||
q = request.GET.get('q')
|
||||
data = _query(q, type_, user=request.user)
|
||||
return render(request, 'search/filtered.html', data)
|
||||
|
||||
|
||||
def me(request):
|
||||
if not request.user.is_authenticated():
|
||||
return redirect(reverse('search.results') + '?' +
|
||||
request.META['QUERY_STRING'])
|
||||
q = request.GET.get('q')
|
||||
data = _query(q, user=request.user, filter_by_user=True)
|
||||
return render(request, 'search/filtered.html', data)
|
||||
|
|
|
@ -119,7 +119,7 @@ JETPACK_ITEMS_PER_PAGE = 10
|
|||
JETPACK_LIB_DIR = 'lib'
|
||||
JETPACK_DATA_DIR = 'data'
|
||||
|
||||
ATTACHMENT_MAX_FILESIZE = 100*1024*1024 # 100kb
|
||||
ATTACHMENT_MAX_FILESIZE = 100 * 1024 * 1024 # 100kb
|
||||
|
||||
PYTHON_EXEC = 'python'
|
||||
|
||||
|
@ -245,7 +245,7 @@ INSTALLED_APPS = [
|
|||
# FLIGHTDECK APPS
|
||||
'base', # basic flightdeck things (utils, urls)
|
||||
'person', # user related stuff (profile etc.)
|
||||
'search', # ElasticSearch and related stuff.
|
||||
'search', # ElasticSearch and search views.
|
||||
'amo', # currently addons.mozilla.org authentication
|
||||
'jetpack', # Jetpack functionality
|
||||
'xpi', # XPI management
|
||||
|
|
7
urls.py
7
urls.py
|
@ -5,10 +5,7 @@ from django.conf import settings
|
|||
from base import views as base_views
|
||||
|
||||
|
||||
urls = [
|
||||
# home
|
||||
url(r'^$', base_views.homepage, name='home'),
|
||||
]
|
||||
urls = [url(r'^$', base_views.homepage, name='home')]
|
||||
|
||||
if settings.DEBUG:
|
||||
|
||||
|
@ -30,10 +27,8 @@ urls.extend([
|
|||
# API Browser
|
||||
(r'^api/', include('api.urls')),
|
||||
|
||||
# Tutorial
|
||||
(r'^tutorial/', include('tutorial.urls')),
|
||||
|
||||
# Person
|
||||
(r'^user/', include('person.urls')),
|
||||
|
||||
# Search
|
||||
|
|
Загрузка…
Ссылка в новой задаче