Initial commit

master
androiddrew 6 years ago
parent 1d7ea8cafc
commit a2e52d453c

2
.gitignore vendored

@ -58,3 +58,5 @@ docs/_build/
# PyBuilder
target/
# Pycharm
.idea/

@ -0,0 +1,5 @@
pytest
pytest-cov
flake8
black
wagtail

@ -0,0 +1,44 @@
#
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --output-file dev_requirements.txt dev_requirements.in
#
--trusted-host pypi.python.org
appdirs==1.4.3 # via black
atomicwrites==1.2.1 # via pytest
attrs==18.2.0 # via black, pytest
beautifulsoup4==4.6.0 # via wagtail
black==18.9b0
certifi==2018.10.15 # via requests
chardet==3.0.4 # via requests
click==7.0 # via black
coverage==4.5.1 # via pytest-cov
django-modelcluster==4.2 # via wagtail
django-taggit==0.23.0 # via wagtail
django-treebeard==4.3 # via wagtail
django==2.1.2 # via django-taggit, django-treebeard, wagtail
djangorestframework==3.9.0 # via wagtail
draftjs-exporter==2.1.3 # via wagtail
flake8==3.6.0
html5lib==1.0.1 # via wagtail
idna==2.7 # via requests
mccabe==0.6.1 # via flake8
more-itertools==4.3.0 # via pytest
pillow==5.3.0 # via wagtail
pluggy==0.8.0 # via pytest
py==1.7.0 # via pytest
pycodestyle==2.4.0 # via flake8
pyflakes==2.0.0 # via flake8
pytest-cov==2.6.0
pytest==3.9.3
pytz==2018.7 # via django, django-modelcluster, wagtail
requests==2.20.0 # via wagtail
six==1.11.0 # via html5lib, more-itertools, pytest, wagtail
toml==0.10.0 # via black
unidecode==1.0.22 # via wagtail
urllib3==1.24 # via requests
wagtail==2.3
webencodings==0.5.1 # via html5lib
willow==1.1 # via wagtail

@ -0,0 +1,21 @@
FROM python:3.7
LABEL maintainer="drew@androiddrew.comw"
ENV PYTHONUNBUFFERED 1
ENV DJANGO_ENV dev
COPY ./requirements.txt /code/requirements.txt
RUN pip install -r /code/requirements.txt
RUN pip install gunicorn
COPY . /code/
WORKDIR /code/
RUN python manage.py migrate
RUN useradd wagtail
RUN chown -R wagtail /code
USER wagtail
EXPOSE 8000
CMD exec gunicorn cms.wsgi:application --bind 0.0.0.0:8000 --workers 3

@ -0,0 +1,149 @@
"""
Django settings for cms project.
Generated by 'django-admin startproject' using Django 2.1.2.
For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BASE_DIR = os.path.dirname(PROJECT_DIR)
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
# Application definition
INSTALLED_APPS = [
"home",
"search",
"wagtail.contrib.forms",
"wagtail.contrib.redirects",
"wagtail.embeds",
"wagtail.sites",
"wagtail.users",
"wagtail.snippets",
"wagtail.documents",
"wagtail.images",
"wagtail.search",
"wagtail.admin",
"wagtail.core",
"modelcluster",
"taggit",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
MIDDLEWARE = [
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"django.middleware.security.SecurityMiddleware",
"wagtail.core.middleware.SiteMiddleware",
"wagtail.contrib.redirects.middleware.RedirectMiddleware",
]
ROOT_URLCONF = "cms.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [os.path.join(PROJECT_DIR, "templates")],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
]
},
}
]
WSGI_APPLICATION = "cms.wsgi.application"
# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# }
# Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
]
# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATICFILES_FINDERS = [
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
]
STATICFILES_DIRS = [os.path.join(PROJECT_DIR, "static")]
# ManifestStaticFilesStorage is recommended in production, to prevent outdated
# Javascript / CSS assets being served from cache (e.g. after a Wagtail upgrade).
# See https://docs.djangoproject.com/en/2.1/ref/contrib/staticfiles/#manifeststaticfilesstorage
STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATIC_URL = "/static/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"
# Wagtail settings
WAGTAIL_SITE_NAME = "datasketch.io"
# Base URL to use when referring to full URLs within the Wagtail admin backend -
# e.g. in notification emails. Don't include '/admin' or a trailing slash
BASE_URL = "https://datasketch.io"

@ -0,0 +1,28 @@
from .base import *
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "gi5#h%%co$&cnxt36b8g13o2$$=)!3v+v^iyp)7!^qvrhr)w3+"
# SECURITY WARNING: define the correct hosts in production!
ALLOWED_HOSTS = ["*"]
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "datasketch",
"USER": "datasketch",
"PASSWORD": os.environ.get("DB_PASSWD") if os.environ.get("DB_PASSWD") else "",
"HOST": os.environ.get("DB_HOST") if os.environ.get("DB_HOST") else "127.0.0.1",
"PORT": "5432",
}
}
try:
from .local import *
except ImportError:
pass

@ -0,0 +1,8 @@
from .base import *
DEBUG = False
try:
from .local import *
except ImportError:
pass

File diff suppressed because one or more lines are too long

@ -0,0 +1,9 @@
{% extends "base.html" %}
{% block body_class %}template-404{% endblock %}
{% block content %}
<h1>Page not found</h1>
<h2>Sorry, this page could not be found.</h2>
{% endblock %}

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html class="no-js">
<head>
<meta charset="utf-8" />
<title>Internal server error</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<h1>Internal server error</h1>
<h2>Sorry, there seems to be an error. Please try again soon.</h2>
</body>
</html>

@ -0,0 +1,41 @@
{% load static wagtailuserbar %}
<!DOCTYPE html>
<html class="no-js">
<head>
<meta charset="utf-8" />
<title>
{% block title %}
{% if self.seo_title %}{{ self.seo_title }}{% else %}{{ self.title }}{% endif %}
{% endblock %}
{% block title_suffix %}
{% with self.get_site.site_name as site_name %}
{% if site_name %}- {{ site_name }}{% endif %}
{% endwith %}
{% endblock %}
</title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
{# Global stylesheets #}
<link rel="stylesheet" type="text/css" href="{% static 'css/tachyons.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/cms.css' %}">
{% block extra_css %}
{# Override this in templates to add extra stylesheets #}
{% endblock %}
</head>
<body class="{% block body_class %}{% endblock %}">
{% wagtailuserbar %}
{% block content %}{% endblock %}
{# Global javascript #}
<script type="text/javascript" src="{% static 'js/cms.js' %}"></script>
{% block extra_js %}
{# Override this in templates to add extra javascript #}
{% endblock %}
</body>
</html>

@ -0,0 +1,32 @@
from django.conf import settings
from django.conf.urls import include, url
from django.contrib import admin
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.core import urls as wagtail_urls
from wagtail.documents import urls as wagtaildocs_urls
from search import views as search_views
urlpatterns = [
url(r"^django-admin/", admin.site.urls),
url(r"^admin/", include(wagtailadmin_urls)),
url(r"^documents/", include(wagtaildocs_urls)),
url(r"^search/$", search_views.search, name="search"),
# For anything not caught by a more specific rule above, hand over to
# Wagtail's page serving mechanism. This should be the last pattern in
# the list:
url(r"", include(wagtail_urls)),
# Alternatively, if you want Wagtail pages to be served from a subpath
# of your site, rather than the site root:
# url(r'^pages/', include(wagtail_urls)),
]
if settings.DEBUG:
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# Serve static and media files from development server
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

@ -0,0 +1,16 @@
"""
WSGI config for cms project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cms.settings.dev")
application = get_wsgi_application()

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("wagtailcore", "0040_page_draft_title")]
operations = [
migrations.CreateModel(
name="HomePage",
fields=[
(
"page_ptr",
models.OneToOneField(
on_delete=models.CASCADE,
parent_link=True,
auto_created=True,
primary_key=True,
serialize=False,
to="wagtailcore.Page",
),
)
],
options={"abstract": False},
bases=("wagtailcore.page",),
)
]

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
from django.db import migrations
def create_homepage(apps, schema_editor):
# Get models
ContentType = apps.get_model("contenttypes.ContentType")
Page = apps.get_model("wagtailcore.Page")
Site = apps.get_model("wagtailcore.Site")
HomePage = apps.get_model("home.HomePage")
# Delete the default homepage
# If migration is run multiple times, it may have already been deleted
Page.objects.filter(id=2).delete()
# Create content type for homepage model
homepage_content_type, __ = ContentType.objects.get_or_create(
model="homepage", app_label="home"
)
# Create a new homepage
homepage = HomePage.objects.create(
title="Home",
draft_title="Home",
slug="home",
content_type=homepage_content_type,
path="00010001",
depth=2,
numchild=0,
url_path="/home/",
)
# Create a site with the new homepage set as the root
Site.objects.create(hostname="localhost", root_page=homepage, is_default_site=True)
def remove_homepage(apps, schema_editor):
# Get models
ContentType = apps.get_model("contenttypes.ContentType")
HomePage = apps.get_model("home.HomePage")
# Delete the default homepage
# Page and Site objects CASCADE
HomePage.objects.filter(slug="home", depth=2).delete()
# Delete content type for homepage model
ContentType.objects.filter(model="homepage", app_label="home").delete()
class Migration(migrations.Migration):
dependencies = [("home", "0001_initial")]
operations = [migrations.RunPython(create_homepage, remove_homepage)]

@ -0,0 +1,7 @@
from django.db import models
from wagtail.core.models import Page
class HomePage(Page):
pass

@ -0,0 +1,7 @@
{% extends "base.html" %}
{% block body_class %}helvetica{% endblock %}
{% block content %}
<h1>Welcome to Datasketch.io!</h1>
{% endblock %}

@ -0,0 +1,10 @@
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cms.settings.dev")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)

@ -0,0 +1,3 @@
Django>=2.1,<2.2
wagtail>=2.3,<2.4
psycopg2>=2.7.5

@ -0,0 +1,38 @@
{% extends "base.html" %}
{% load static wagtailcore_tags %}
{% block body_class %}template-searchresults{% endblock %}
{% block title %}Search{% endblock %}
{% block content %}
<h1>Search</h1>
<form action="{% url 'search' %}" method="get">
<input type="text" name="query"{% if search_query %} value="{{ search_query }}"{% endif %}>
<input type="submit" value="Search" class="button">
</form>
{% if search_results %}
<ul>
{% for result in search_results %}
<li>
<h4><a href="{% pageurl result %}">{{ result }}</a></h4>
{% if result.search_description %}
{{ result.search_description }}
{% endif %}
</li>
{% endfor %}
</ul>
{% if search_results.has_previous %}
<a href="{% url 'search' %}?query={{ search_query|urlencode }}&amp;page={{ search_results.previous_page_number }}">Previous</a>
{% endif %}
{% if search_results.has_next %}
<a href="{% url 'search' %}?query={{ search_query|urlencode }}&amp;page={{ search_results.next_page_number }}">Next</a>
{% endif %}
{% elif search_query %}
No results found
{% endif %}
{% endblock %}

@ -0,0 +1,35 @@
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.shortcuts import render
from wagtail.core.models import Page
from wagtail.search.models import Query
def search(request):
search_query = request.GET.get("query", None)
page = request.GET.get("page", 1)
# Search
if search_query:
search_results = Page.objects.live().search(search_query)
query = Query.get(search_query)
# Record hit
query.add_hit()
else:
search_results = Page.objects.none()
# Pagination
paginator = Paginator(search_results, 10)
try:
search_results = paginator.page(page)
except PageNotAnInteger:
search_results = paginator.page(1)
except EmptyPage:
search_results = paginator.page(paginator.num_pages)
return render(
request,
"search/search.html",
{"search_query": search_query, "search_results": search_results},
)
Loading…
Cancel
Save