Skip to content
This repository has been archived by the owner on Jul 22, 2022. It is now read-only.

Commit

Permalink
Merge pull request #26 from makyo/add-haystack
Browse files Browse the repository at this point in the history
Initial pass at search
  • Loading branch information
makyo committed Oct 29, 2016
2 parents 7e6dcde + 7da1d80 commit 1ce0b69
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 9 deletions.
2 changes: 1 addition & 1 deletion core/fixtures/flatpages.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"model": "flatpages.flatpage", "pk": 1, "fields": {"url": "/about/terms/", "title": "Terms of Service", "content": "<p>Here is where you should include your terms of service. This should generally work as follows, according to wikipedia:</p>\r\n\r\n<ul>\r\n<li>Disambiguation/definition of key words and phrases</li>\r\n<li>User rights and responsibilities\r\n<ul>\r\n<li>Proper or expected usage; potential misuse</li>\r\n<li>Accountability for online actions, behavior, and conduct</li>\r\n<li>Privacy policy outlining the use of personal data</li>\r\n<li>Payment details such as membership or subscription fees, etc.</li>\r\n<li>Opt-out policy describing procedure for account termination, if available</li>\r\n</ul>\r\n</li>\r\n<li>Disclaimer/Limitation of Liability clarifying the site's legal liability for damages incurred by users</li>\r\n<li>Any warrant canaries</li>\r\n<li>User notification upon modification of terms, if offered</li>\r\n</ul>", "enable_comments": false, "template_name": "", "registration_required": false, "sites": [1]}}, {"model": "flatpages.flatpage", "pk": 2, "fields": {"url": "/about/aup/", "title": "Acceptable Upload Policy", "content": "<p>Here is where you would set your acceptable upload policy. Consider informing users about:</p>\r\n<ul>\r\n<li>Who may upload whose works (own, commissions, other)</li>\r\n<li>Restricted subject matter</li>\r\n<li>Content writing</li>\r\n</ul>", "enable_comments": false, "template_name": "", "registration_required": false, "sites": [1]}}, {"model": "flatpages.flatpage", "pk": 3, "fields": {"url": "/about/help/", "title": "Honeycomb Help", "content": "Help for Honeycomb", "enable_comments": false, "template_name": "", "registration_required": false, "sites": [1]}}, {"model": "flatpages.flatpage", "pk": 4, "fields": {"url": "/about/markdown/", "title": "Markdown help", "content": "Help for markdown", "enable_comments": false, "template_name": "", "registration_required": false, "sites": [1]}}, {"model": "flatpages.flatpage", "pk": 5, "fields": {"url": "/about/credits/", "title": "Credits", "content": "<!--\r\nDear site staff,\r\n\r\nThe creators of Honeycomb respectfully request that this page be left intact, or at least without any subtractions. If you need to add anything, feel free, but it's important that the labor that goes into a project like this be recognized.\r\n\r\nCheers,\r\n\r\nHoneycomb\r\n-->\r\n\r\n<p>Credit where credit is due! The inspiration for Honeycomb came from a discussion among members of <a href=\"https://furrywritersguild.com\" target=\"_blank\">The Furry Writers' Guild</a> on what an ideal writing site should be. It should be:</p>\r\n\r\n<ul>\r\n<li>easy to post one's work</li>\r\n<li>easy to interact socially with other users</li>\r\n<li>easy to promote works to others through promotions or editor highlights</li>\r\n<li>easy to organize work through tags and folders</li>\r\n<li>easy to discover new authors and their work</li>\r\n<li>easy for publishers to maintain a presence through pages and advertising</li>\r\n</ul>\r\n\r\n<p>From out of the FWGs discussions came a specification, which was picked up by <a href=\"http://openfurry.org\">OpenFurry</a> as a project. The intent was to provide an implementation and website for use by the furry subculture. The project was open-sourced to allow other communities of writers and readers to use it and contribute as well!</p>\r\n\r\n<p>Additionally, the following resources contributed to make the Honeycomb project what it is:</p>\r\n\r\n<dl class=\"dl-horizontal\">\r\n<dt><a href=\"https://djangoproject.com\" target=\"_blank\">Django</a></dt>\r\n<dd>Django is the framework upon which Honeycomb is built</dd>\r\n<dt><a href=\"https://getbootstrap.com\" target=\"_blank\">Bootstrap</a></dt>\r\n<dd>Bootstrap provides the stylistic framework for the site</dd>\r\n<dt><a href=\"https://glyphicons.com\" target=\"_blank\">Glyphicons</a></dt>\r\n<dd>The Glyphicons icon font provides most of the icons you see throughout the site</dd>\r\n<dt><a href=\"django-nose.readthedocs.io/en/latest/\" target=\"_blank\">django-nose</a></dt>\r\n<dd><code>django-nose</code> provides additional testing framework for Honeycomb</dd>\r\n<dt><a href=\"https://github.com/alex/django-taggit\" target=\"_blank\">django-taggit</a></dt>\r\n<dd><code>django-taggit</code> provides the mechanism used for tagging submissions</dd>\r\n<dt><a href=\"https://coveralls.io/\" target=\"_blank\">Coveralls.io</a></dt>\r\n<dd>Coveralls ensures that test coverage remains above a certain level. Current coverage of the master branch of Honeycomb is <a target=\"_blank\" href='https://coveralls.io/github/OpenFurry/honeycomb?branch=master'><img src='https://coveralls.io/repos/github/OpenFurry/honeycomb/badge.svg?branch=master' alt='Coverage Status' /></a></dd>\r\n<dt><a href=\"https://travis-ci.org/\" target=\"_blank\">Coveralls.io</a></dt>\r\n<dd>Travis CI ensures that all tests pass whenever a change is made to the source code of Honeycomb. The current build status of the master branch of Honeycomb is <a target=\"_blank\" href=\"https://travis-ci.org/OpenFurry/honeycomb\"><img src=\"https://travis-ci.org/OpenFurry/honeycomb.svg?branch=master\" /></a></dd>\r\n</dl>", "enable_comments": false, "template_name": "", "registration_required": false, "sites": [1]}}]
[{"model": "flatpages.flatpage", "pk": 1, "fields": {"url": "/about/terms/", "title": "Terms of Service", "content": "<p>Here is where you should include your terms of service. This should generally work as follows, according to wikipedia:</p>\r\n\r\n<ul>\r\n<li>Disambiguation/definition of key words and phrases</li>\r\n<li>User rights and responsibilities\r\n<ul>\r\n<li>Proper or expected usage; potential misuse</li>\r\n<li>Accountability for online actions, behavior, and conduct</li>\r\n<li>Privacy policy outlining the use of personal data</li>\r\n<li>Payment details such as membership or subscription fees, etc.</li>\r\n<li>Opt-out policy describing procedure for account termination, if available</li>\r\n</ul>\r\n</li>\r\n<li>Disclaimer/Limitation of Liability clarifying the site's legal liability for damages incurred by users</li>\r\n<li>Any warrant canaries</li>\r\n<li>User notification upon modification of terms, if offered</li>\r\n</ul>", "enable_comments": false, "template_name": "", "registration_required": false, "sites": [1]}}, {"model": "flatpages.flatpage", "pk": 2, "fields": {"url": "/about/aup/", "title": "Acceptable Upload Policy", "content": "<p>Here is where you would set your acceptable upload policy. Consider informing users about:</p>\r\n<ul>\r\n<li>Who may upload whose works (own, commissions, other)</li>\r\n<li>Restricted subject matter</li>\r\n<li>Content writing</li>\r\n</ul>", "enable_comments": false, "template_name": "", "registration_required": false, "sites": [1]}}, {"model": "flatpages.flatpage", "pk": 3, "fields": {"url": "/about/help/", "title": "Honeycomb Help", "content": "Help for Honeycomb", "enable_comments": false, "template_name": "", "registration_required": false, "sites": [1]}}, {"model": "flatpages.flatpage", "pk": 4, "fields": {"url": "/about/markdown/", "title": "Markdown help", "content": "Help for markdown", "enable_comments": false, "template_name": "", "registration_required": false, "sites": [1]}}, {"model": "flatpages.flatpage", "pk": 5, "fields": {"url": "/about/credits/", "title": "Credits", "content": "<!--\r\nDear site staff,\r\n\r\nThe creators of Honeycomb respectfully request that this page be left intact, or at least without any subtractions. If you need to add anything, feel free, but it's important that the labor that goes into a project like this be recognized.\r\n\r\nCheers,\r\n\r\nHoneycomb\r\n-->\r\n\r\n<p>Credit where credit is due! The inspiration for Honeycomb came from a discussion among members of <a href=\"https://furrywritersguild.com\" target=\"_blank\">The Furry Writers' Guild</a> on what an ideal writing site should be. It should be:</p>\r\n\r\n<ul>\r\n<li>easy to post one's work</li>\r\n<li>easy to interact socially with other users</li>\r\n<li>easy to promote works to others through promotions or editor highlights</li>\r\n<li>easy to organize work through tags and folders</li>\r\n<li>easy to discover new authors and their work</li>\r\n<li>easy for publishers to maintain a presence through pages and advertising</li>\r\n</ul>\r\n\r\n<p>From out of the FWGs discussions came a specification, which was picked up by <a href=\"http://openfurry.org\">OpenFurry</a> as a project. The intent was to provide an implementation and website for use by the furry subculture. The project was open-sourced to allow other communities of writers and readers to use it and contribute as well!</p>\r\n\r\n<p>Additionally, the following resources contributed to make the Honeycomb project what it is:</p>\r\n\r\n<dl>\r\n<dt><a href=\"https://djangoproject.com\" target=\"_blank\">Django</a></dt>\r\n<dd>Django is the framework upon which Honeycomb is built</dd>\r\n<dt><a href=\"https://getbootstrap.com\" target=\"_blank\">Bootstrap</a></dt>\r\n<dd>Bootstrap provides the stylistic framework for the site</dd>\r\n<dt><a href=\"https://glyphicons.com\" target=\"_blank\">Glyphicons</a></dt>\r\n<dd>The Glyphicons icon font provides most of the icons you see throughout the site</dd>\r\n<dt><a href=\"django-nose.readthedocs.io/en/latest/\" target=\"_blank\">django-nose</a></dt>\r\n<dd><code>django-nose</code> provides additional testing framework for Honeycomb</dd>\r\n<dt><a href=\"https://github.com/alex/django-taggit\" target=\"_blank\">django-taggit</a></dt>\r\n<dd><code>django-taggit</code> provides the mechanism used for tagging submissions</dd>\r\n<dt><a href=\"http://haystacksearch.org\" target=\"_blank\">Haystack</a></dt>\r\n<dd>Haystack provides Honeycomb's search functionality</dd>\r\n<dt><a href=\"https://coveralls.io/\" target=\"_blank\">Coveralls.io</a></dt>\r\n<dd>Coveralls ensures that test coverage remains above a certain level. Current coverage of the master branch of Honeycomb is <a target=\"_blank\" href='https://coveralls.io/github/OpenFurry/honeycomb?branch=master'><img src='https://coveralls.io/repos/github/OpenFurry/honeycomb/badge.svg?branch=master' alt='Coverage Status' /></a></dd>\r\n<dt><a href=\"https://travis-ci.org/\" target=\"_blank\">Coveralls.io</a></dt>\r\n<dd>Travis CI ensures that all tests pass whenever a change is made to the source code of Honeycomb. The current build status of the master branch of Honeycomb is <a target=\"_blank\" href=\"https://travis-ci.org/OpenFurry/honeycomb\"><img src=\"https://travis-ci.org/OpenFurry/honeycomb.svg?branch=master\" /></a></dd>\r\n</dl>", "enable_comments": false, "template_name": "", "registration_required": false, "sites": [1]}}]
17 changes: 17 additions & 0 deletions core/search_indexes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import datetime
from haystack import indexes
from submissions.models import Submission


class SubmissionIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
author = indexes.CharField(model_attr='owner')
pub_date = indexes.DateTimeField(model_attr='ctime')

def get_model(self):
return Submission

def index_queryset(self, using=None):
"""Used when the entire index for model is updated."""
return self.get_model().objects.filter(
ctime__lte=datetime.datetime.now())
10 changes: 10 additions & 0 deletions core/static/app/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ body {
border-bottom: none;
}

.search-form .input-group {
width: 100%;
}
.search-form .form-control {
width: 80%;
}
.search-form .input-group-btn {
width: 20%;
}

textarea {
font-family: monospace;
}
Expand Down
4 changes: 2 additions & 2 deletions core/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<form class="navbar-form navbar-left" method="get" action="{% url 'core:basic_search' %}">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search">
<input type="text" class="form-control" placeholder="Search" name="q" />
<span class="input-group-btn">
<button type="submit" class="btn btn-default">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
Expand Down
8 changes: 4 additions & 4 deletions core/templates/flatpages/default.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{% extends "base.html" %}

{% block content %}
{% if user.is_staff %}
<a class="btn btn-primary" role="button" href="{% url 'admin:flatpages_flatpage_change' flatpage.id %}">Edit</a>
{% endif %}
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="col-md-8 col-md-offset-2">
{{ flatpage.content|safe }}
{% if user.is_staff %}
<p><a class="btn btn-primary" role="button" href="{% url 'admin:flatpages_flatpage_change' flatpage.id %}">Edit</a></p>
{% endif %}
</div>
</div>
{% endblock %}
5 changes: 5 additions & 0 deletions core/templates/search/indexes/submissions/submission_text.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{{ object.title }}
{{ object.owner.username }}
{{ object.owner.get_display_name }}
{{ object.description_rendered|striptags }}
{{ object.content_rendered|striptags }}
69 changes: 69 additions & 0 deletions core/templates/search/search.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{% extends 'base.html' %}
{% load form_extras %}

{% block content %}
<header class="page-header">
<h1>Search</h1>
</header>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form method="get" class="form-inline search-form">
{{ form.q.label_tag }}
<div class="input-group">
{{ form.q|append_form_control }}
<span class="input-group-btn">
<button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span> Search</button>
</span>
</div>

{% if query %}
<h3>Results</h3>

{% for result in page.object_list %}
{% include "submission-list-snippet.html" with submission=result.object %}
{% empty %}
<p>No results found.</p>
{% endfor %}

{% if page.has_previous or page.has_next %}
<div class="row">
<div class="col-md-12 text-center">
<nav aria-label="Search result pages">
<ul class="pagination">
{% if page.has_previous %}
<li>
<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}/" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% else %}
<li class="disabled"><span aria-hidden="true">&laquo;</span></li>
{% endif %}
{% for page_num in page.paginator.page_range %}
{% if page.number == page_num %}
<li class="active"><a href="?q={{ query }}&amp;page={{ page_num }}/">{{ page_num }} <span class="sr-only">(current)</span></a></li>
{% else %}
<li><a href="?q={{ query }}&amp;page={{ page_num }}/">{{ page_num }}</a></li>
{% endif %}
{% endfor %}
{% if submissions.has_next %}
<li>
<a href="?q={{ query }}&amp;page={{ page.next_page_number }}/" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% else %}
<li class="disabled"><span aria-hidden="true">&raquo;</span></li>
{% endif %}
</ul>
</nav>
</div>
</div>
{% endif %}
{% else %}
{# Show some example queries to run, maybe query syntax, something else? #}
{% endif %}
</form>
</div>
</div>
{% endblock %}
2 changes: 2 additions & 0 deletions core/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.conf.urls import url

from .views import (
BasicSearchView,
flatpage_list,
front,
)
Expand All @@ -9,4 +10,5 @@
urlpatterns = [
url('^$', front, name='front'),
url('^about/$', flatpage_list, name="flatpage_list"),
url('^search/$', BasicSearchView.as_view(), name='basic_search'),
]
7 changes: 7 additions & 0 deletions core/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from django.core.urlresolvers import reverse
from django.shortcuts import render
from haystack.generic_views import SearchView
from haystack.forms import SearchForm


def front(request):
Expand All @@ -11,3 +13,8 @@ def flatpage_list(request):
'title': 'About',
'prefix': reverse('core:flatpage_list'),
})


class BasicSearchView(SearchView):
template_name = 'search/search.html'
form_class = SearchForm
4 changes: 2 additions & 2 deletions coverage-badge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified db.sqlite3
Binary file not shown.
6 changes: 6 additions & 0 deletions honeycomb/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
'publishers',
'promotion',
'taggit',
'haystack',
'django_nose',
'django.contrib.admin',
'django.contrib.auth',
Expand Down Expand Up @@ -146,6 +147,11 @@


# Additional configuration for Honeycomb
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.simple_backend.SimpleEngine',
},
}
SUBMISSION_BASE = ('^~(?P<username>[^/]+)/(?P<submission_id>\d+)-'
'(?P<submission_slug>[-\w]+)/')
LOGOUT_REDIRECT_URL = "/login/"
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ configparser==3.5.0
coverage==4.0.3
coverage-badge==0.1.2
Django==1.10.2
django-haystack==2.5.1
django-nose==1.4.4
django-taggit==0.21.3
enum34==1.1.6
Expand Down

0 comments on commit 1ce0b69

Please sign in to comment.