Skip to content

Commit bb55433

Browse files
committed
Initial import. Still very alpha.
0 parents  commit bb55433

File tree

12 files changed

+172
-0
lines changed

12 files changed

+172
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.DS_Store
2+
*.pyc

AUTHORS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Primary author:
2+
3+
* Daniel Lindsley
4+
5+
Contributors:
6+
7+
*

LICENSE

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Copyright (c) 2010, Daniel Lindsley.
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without modification,
5+
are permitted provided that the following conditions are met:
6+
7+
1. Redistributions of source code must retain the above copyright notice,
8+
this list of conditions and the following disclaimer.
9+
10+
2. Redistributions in binary form must reproduce the above copyright
11+
notice, this list of conditions and the following disclaimer in the
12+
documentation and/or other materials provided with the distribution.
13+
14+
3. Neither the name of saved_searches nor the names of its contributors may
15+
be used to endorse or promote products derived from this software without
16+
specific prior written permission.
17+
18+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=============
2+
saved_searches
3+
=============
4+
5+
Allows you to personalize search by storing a user's search history.
6+
7+
For use with Haystack (http://haystacksearch.org/).
8+
9+
10+
Requirements
11+
============
12+
13+
* Django 1.1+ (May work on 1.0.X but untested)
14+
* Haystack 1.X (http://github.com/toastdriven/django-haystack)
15+
16+
17+
Setup
18+
=====
19+
20+
#. Add ``saved_searches`` to ``INSTALLED_APPS``.
21+
#. ``./manage.py syncdb``.
22+
#. Alter either your URLconfs to use the ``saved_searches.views.SavedSearchView``
23+
or change the inheritance of your subclassed views.

TODO

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
TODO
2+
====
3+
4+
- Tests.
5+
- Add a template tag for fetching a user's searches.
6+
- Add aggregated views to see all activity (omitting user information).
7+
- Perhaps add an AJAX view that returns suggested searches?

saved_searches/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
__author__ = 'Daniel Lindsley'
2+
__version__ = ('1', '0', '0', 'alpha')

saved_searches/admin.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from django.contrib import admin
2+
from saved_searches.models import SavedSearch
3+
4+
5+
class SavedSearchAdmin(admin.ModelAdmin):
6+
date_hierarchy = 'created'
7+
list_display = ('user_query', 'search_key', 'user', 'result_count', 'created')
8+
list_filter = ('search_key',)
9+
raw_id_fields = ('user',)
10+
search_fields = ('user_query', 'search_key')
11+
12+
13+
site.register(SavedSearch, SavedSearchAdmin)

saved_searches/models.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import datetime
2+
from django.contrib.auth.models import User
3+
from django.db import models
4+
5+
6+
class SavedSearch(models.Model):
7+
search_key = models.SlugField(max_length=100, help_text="A way to arbitrarily group queries. Should be a single word. Example: all-products")
8+
user_query = models.CharField(max_length=1000, help_text="The text the user searched on. Useful for display.")
9+
full_query = models.CharField(max_length=1000, help_text="The full query Haystack generated. Useful for searching again.")
10+
result_count = models.PositiveIntegerField(default=0)
11+
user = models.ForeignKey(User, blank=True, null=True, related_name='saved_searches')
12+
created = models.DateTimeField(default=datetime.datetime.now)
13+
14+
def __unicode__(self):
15+
if self.user:
16+
return u"'%s...' by %s:%s" % (self.user_query[:50], self.user.username, self.search_key)
17+
18+
return u"'%s...' by Anonymous:%s" % (self.user_query[:50], self.search_key)

saved_searches/tests/__init__.py

Whitespace-only changes.

saved_searches/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# DRL_TODO: Create aggregated views and hook them up here.

saved_searches/views.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from haystack.views import SearchView
2+
from saved_searches.models import SavedSearch
3+
4+
5+
class SavedSearchView(SearchView):
6+
search_key = 'general'
7+
8+
def __init__(self, *args, **kwargs):
9+
if 'search_key' in kwargs:
10+
self.search_key = kwargs['search_key']
11+
del(kwargs['search_key'])
12+
13+
super(SavedSearchView, self).__init__(*args, **kwargs)
14+
15+
def create_response(self):
16+
"""
17+
Saves the details of a user's search and then generates the actual
18+
HttpResponse to send back to the user.
19+
"""
20+
(paginator, page) = self.build_page()
21+
22+
saved_search = SavedSearch(
23+
search_key=self.search_key,
24+
user_query=self.query,
25+
result_count=paginator.count
26+
)
27+
28+
query_seen = self.searchqueryset.query.build_query()
29+
30+
if isinstance(query_seen, basestring):
31+
saved_search.full_query = query_seen
32+
33+
if request.user.is_authenticated():
34+
saved_search.user = request.user
35+
36+
saved_search.save()
37+
38+
context = {
39+
'query': self.query,
40+
'form': self.form,
41+
'page': page,
42+
'paginator': paginator,
43+
}
44+
context.update(self.extra_context())
45+
46+
return render_to_response(self.template, context, context_instance=self.context_class(self.request))

setup.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
from distutils.core import setup
4+
5+
setup(
6+
name='saved_searches',
7+
version='1.0.0-alpha',
8+
description='Saves user searches for integration with Haystack.',
9+
author='Daniel Lindsley',
10+
author_email='[email protected]',
11+
url='http://github.com/toastdriven/saved_searches',
12+
packages=[
13+
'saved_searches',
14+
'queued_search.templatetags',
15+
],
16+
classifiers=[
17+
'Development Status :: 4 - Beta',
18+
'Environment :: Web Environment',
19+
'Framework :: Django',
20+
'Intended Audience :: Developers',
21+
'License :: OSI Approved :: BSD License',
22+
'Operating System :: OS Independent',
23+
'Programming Language :: Python',
24+
'Topic :: Utilities'
25+
],
26+
)

0 commit comments

Comments
 (0)