Pēteris Caune
2 years ago
No known key found for this signature in database
GPG Key ID: E28D7679E9A9EDE2
14 changed files with 254 additions and 85 deletions
-
1CHANGELOG.md
-
4hc/front/forms.py
-
38hc/front/management/commands/populate_searchdb.py
-
17hc/front/tests/test_search.py
-
1hc/front/urls.py
-
66hc/front/views.py
-
10hc/lib/html.py
-
BINsearch.db
-
23static/css/search.css
-
31static/js/search.js
-
1templates/base.html
-
61templates/front/base_docs.html
-
14templates/front/docs_search.html
-
72templates/front/docs_single.html
@ -0,0 +1,38 @@ |
|||
import os |
|||
import sqlite3 |
|||
|
|||
from django.conf import settings |
|||
from django.core.management.base import BaseCommand |
|||
from hc.front.views import _replace_placeholders |
|||
from hc.lib.html import html2text |
|||
|
|||
|
|||
class Command(BaseCommand): |
|||
help = "Renders Markdown to HTML" |
|||
|
|||
def handle(self, *args, **options): |
|||
con = sqlite3.connect(os.path.join(settings.BASE_DIR, "search.db")) |
|||
cur = con.cursor() |
|||
cur.execute("DROP TABLE IF EXISTS docs") |
|||
cur.execute( |
|||
"""CREATE VIRTUAL TABLE docs USING FTS5(slug, title, body, tokenize="trigram")""" |
|||
) |
|||
|
|||
docs_path = os.path.join(settings.BASE_DIR, "templates/docs") |
|||
for filename in os.listdir(docs_path): |
|||
if not filename.endswith(".html"): |
|||
continue |
|||
|
|||
slug = filename[:-5] # cut ".html" |
|||
print("Processing %s" % slug) |
|||
|
|||
html = open(os.path.join(docs_path, filename), "r").read() |
|||
html = _replace_placeholders(slug, html) |
|||
|
|||
lines = html.split("\n") |
|||
title = html2text(lines[0]) |
|||
text = html2text("\n".join(lines[1:]), skip_pre=True) |
|||
|
|||
cur.execute("INSERT INTO docs VALUES (?, ?, ?)", (slug, title, text)) |
|||
|
|||
con.commit() |
@ -0,0 +1,17 @@ |
|||
from hc.test import BaseTestCase |
|||
|
|||
|
|||
class SearchTestCase(BaseTestCase): |
|||
def test_it_works(self): |
|||
r = self.client.get("/docs/search/?q=failure") |
|||
self.assertContains( |
|||
r, "You can actively signal a <span>failure</span>", status_code=200 |
|||
) |
|||
|
|||
def test_it_handles_no_results(self): |
|||
r = self.client.get("/docs/search/?q=asfghjkl") |
|||
self.assertContains(r, "Your search query matched no results", status_code=200) |
|||
|
|||
def test_it_rejects_special_characters(self): |
|||
r = self.client.get("/docs/search/?q=api/v1") |
|||
self.assertContains(r, "Your search query matched no results", status_code=200) |
@ -0,0 +1,23 @@ |
|||
@media (min-width: 992px) { |
|||
#docs-search-form { |
|||
margin-right: 20%; |
|||
} |
|||
} |
|||
|
|||
#search-results { |
|||
display: none; |
|||
} |
|||
|
|||
#search-results.on { |
|||
display: block; |
|||
} |
|||
|
|||
.docs-nav.off { |
|||
display: none; |
|||
} |
|||
|
|||
#search-results li span { |
|||
background: #ffef82; |
|||
border-radius: 2px; |
|||
color: #111; |
|||
} |
@ -0,0 +1,31 @@ |
|||
$(function() { |
|||
var base = document.getElementById("base-url").getAttribute("href").slice(0, -1); |
|||
var input = $("#docs-search"); |
|||
|
|||
input.on("keyup focus", function() { |
|||
var q = this.value; |
|||
if (q.length < 3) { |
|||
$("#search-results").removeClass("on"); |
|||
$("#docs-nav").removeClass("off"); |
|||
return |
|||
} |
|||
|
|||
$.ajax({ |
|||
url: base + "/docs/search/", |
|||
type: "get", |
|||
data: {q: q}, |
|||
success: function(data) { |
|||
if (q != input.val()) { |
|||
return; // ignore stale results
|
|||
} |
|||
|
|||
$("#search-results").html(data).addClass("on"); |
|||
$("#docs-nav").addClass("off"); |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
// input.on("blur", function() {
|
|||
// $("#search-results").removeClass("on");
|
|||
// });
|
|||
}); |
@ -1,61 +0,0 @@ |
|||
{% extends "base.html" %} |
|||
{% load hc_extras %} |
|||
|
|||
|
|||
{% block content %} |
|||
<div class="row"> |
|||
<div class="col-sm-3"> |
|||
|
|||
<ul class="docs-nav"> |
|||
<li class="nav-header">{{ site_name }}</li> |
|||
<li {% if section == "introduction" %} class="active"{% endif %}> |
|||
<a href="{% url 'hc-docs' %}">Introduction</a> |
|||
</li> |
|||
{% include "front/docs_nav_item.html" with slug="configuring_checks" title="Configuring checks" %} |
|||
{% include "front/docs_nav_item.html" with slug="configuring_notifications" title="Configuring notifications" %} |
|||
{% include "front/docs_nav_item.html" with slug="projects_teams" title="Projects and teams" %} |
|||
{% include "front/docs_nav_item.html" with slug="badges" title="Badges" %} |
|||
|
|||
<li class="nav-header">API</li> |
|||
{% include "front/docs_nav_item.html" with slug="http_api" title="Pinging API" %} |
|||
{% include "front/docs_nav_item.html" with slug="api" title="Management API" %} |
|||
|
|||
<li class="nav-header">Pinging Examples</li> |
|||
{% include "front/docs_nav_item.html" with slug="reliability_tips" title="Reliability Tips" %} |
|||
{% include "front/docs_nav_item.html" with slug="bash" title="Shell scripts" %} |
|||
{% include "front/docs_nav_item.html" with slug="python" title="Python" %} |
|||
{% include "front/docs_nav_item.html" with slug="ruby" title="Ruby" %} |
|||
{% include "front/docs_nav_item.html" with slug="php" title="PHP" %} |
|||
{% include "front/docs_nav_item.html" with slug="go" title="Go" %} |
|||
{% include "front/docs_nav_item.html" with slug="csharp" title="C#" %} |
|||
{% include "front/docs_nav_item.html" with slug="javascript" title="Javascript" %} |
|||
{% include "front/docs_nav_item.html" with slug="powershell" title="PowerShell" %} |
|||
{% include "front/docs_nav_item.html" with slug="email" title="Email" %} |
|||
|
|||
<li class="nav-header">Guides</li> |
|||
{% include "front/docs_nav_item.html" with slug="monitoring_cron_jobs" title="Monitoring cron jobs" %} |
|||
{% include "front/docs_nav_item.html" with slug="signaling_failures" title="Signaling failures" %} |
|||
{% include "front/docs_nav_item.html" with slug="measuring_script_run_time" title="Measuring script run time" %} |
|||
{% include "front/docs_nav_item.html" with slug="attaching_logs" title="Attaching logs" %} |
|||
{% include "front/docs_nav_item.html" with slug="cloning_checks" title="Cloning checks" %} |
|||
{% include "front/docs_nav_item.html" with slug="configuring_prometheus" title="Configuring Prometheus" %} |
|||
|
|||
<li class="nav-header">Developer Tools</li> |
|||
{% include "front/docs_nav_item.html" with slug="resources" title="Third-party resources" %} |
|||
|
|||
<li class="nav-header">Self-hosted</li> |
|||
{% include "front/docs_nav_item.html" with slug="self_hosted" title="Overview" %} |
|||
{% include "front/docs_nav_item.html" with slug="self_hosted_configuration" title="Configuration" %} |
|||
{% include "front/docs_nav_item.html" with slug="self_hosted_docker" title="Running with Docker" %} |
|||
|
|||
<li class="nav-header">Reference</li> |
|||
<li><a href="{% url 'hc-docs-cron' %}">Cron syntax cheatsheet</a></li> |
|||
</ul> |
|||
|
|||
</div> |
|||
<div class="col-sm-9"> |
|||
{% block docs_content %} |
|||
{% endblock %} |
|||
</div> |
|||
</div> |
|||
{% endblock %} |
@ -0,0 +1,14 @@ |
|||
<ul class="docs-nav"> |
|||
<li class="nav-header">Search Results</li> |
|||
{% if results %} |
|||
{% for slug, title, snippet in results %} |
|||
<li> |
|||
<a href="{% url 'hc-serve-doc' slug %}">{{ title|safe }}</a> |
|||
<p>{{ snippet|safe }}</p> |
|||
</li> |
|||
{% endfor %} |
|||
</ul> |
|||
{% else %} |
|||
<li>Your search query matched no results.</li> |
|||
{% endif %} |
|||
</ul> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue