stuff
This commit is contained in:
parent
ca61adc1e6
commit
79d441d1f6
|
@ -0,0 +1,10 @@
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
build: ./franklincce
|
||||||
|
command: gunicorn franklincce.wsgi:application --bind 0.0.0.0:8000
|
||||||
|
volumes:
|
||||||
|
- ./franklincce/:/usr/src/franklincce
|
||||||
|
ports:
|
||||||
|
- 8000:8000
|
|
@ -0,0 +1,20 @@
|
||||||
|
FROM python:3.11.4-slim-buster
|
||||||
|
|
||||||
|
# set work directory
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
|
# set environment variables
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE 1
|
||||||
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
|
# install dependencies
|
||||||
|
RUN pip install --upgrade pip
|
||||||
|
COPY ./requirements.txt .
|
||||||
|
RUN pip install -r requirements.txt
|
||||||
|
|
||||||
|
|
||||||
|
# copy project
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN mkdir /var/www/static -p
|
||||||
|
RUN python3 manage.py collectstatic --noinput
|
|
@ -5,6 +5,8 @@ from .lib.parsers import HSYIG, HSMUN
|
||||||
import io
|
import io
|
||||||
import fitz
|
import fitz
|
||||||
|
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
class LegislationBook(models.Model):
|
class LegislationBook(models.Model):
|
||||||
class ConferenceType(models.TextChoices):
|
class ConferenceType(models.TextChoices):
|
||||||
MIDDLE = "M", _("Middle School")
|
MIDDLE = "M", _("Middle School")
|
||||||
|
@ -106,3 +108,7 @@ class LegislativeText(models.Model):
|
||||||
self.committee,
|
self.committee,
|
||||||
self.docket_order,
|
self.docket_order,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_lines(self):
|
||||||
|
cls = namedtuple('LegLine', ['linenumber', 'linetext'])
|
||||||
|
return [cls(i + 1, j) for i, j in enumerate(self.text.split('\n'))]
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
{% extends "explorer/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>All legislative texts</h1>
|
||||||
|
|
||||||
|
{% if legislative_texts %}
|
||||||
|
<ul>
|
||||||
|
{% for text in legislative_texts %}
|
||||||
|
<li><a href="{% url 'viewleg' text.id %}">{{ text.legislation_title }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<p>No texts available</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock content %}
|
|
@ -0,0 +1,29 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
{% if page_title %}
|
||||||
|
<title>explorer - {{ title }}</title>
|
||||||
|
{% else %}
|
||||||
|
<title>explorer</title>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<nav id="navbar">
|
||||||
|
<div id="leftnav">
|
||||||
|
<a href="/explorer">explorer</a>
|
||||||
|
</div>
|
||||||
|
<div id="rightnav">
|
||||||
|
<a href="/explorer/all">all</a>
|
||||||
|
<a href="/explorer/topics">by topic</a>
|
||||||
|
<a href="/explorer/search">search</a>
|
||||||
|
<a href="/explorer/stats">stats</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% endblock content %}
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,3 +1,12 @@
|
||||||
|
{% extends "explorer/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Welcome to explorer</h1>
|
||||||
|
|
||||||
|
<p><i>an interactive database for YMCA CCE legislation</i></p>
|
||||||
|
|
||||||
|
<h2>Some randomly selected legislation</h2>
|
||||||
|
|
||||||
{% if legislative_texts %}
|
{% if legislative_texts %}
|
||||||
<ul>
|
<ul>
|
||||||
{% for text in legislative_texts %}
|
{% for text in legislative_texts %}
|
||||||
|
@ -7,3 +16,4 @@
|
||||||
{% else %}
|
{% else %}
|
||||||
<p>No texts available</p>
|
<p>No texts available</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endblock content %}
|
||||||
|
|
|
@ -1,9 +1,24 @@
|
||||||
<h1>{{ legislation.legislation_title }}</h1>
|
{% extends "explorer/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div id="legcontainer">
|
||||||
|
<div id="leginfo" class="boxed">
|
||||||
|
<h1 class="no-margin-top wrapword">{{ legislation.legislation_title }}</h1>
|
||||||
|
|
||||||
<i>{{ legislation.assembly }}/{{ legislation.committee }}/{{ legislation.docket_order }}</i>
|
<i>{{ legislation.assembly }}/{{ legislation.committee }}/{{ legislation.docket_order }}</i>
|
||||||
|
|
||||||
<p>Sponsored by {{ legislation.sponsors }} of {{ legislation.school }}</p>
|
<p>Sponsored by {{ legislation.sponsors }} of {{ legislation.school }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<blockquote>
|
<div id="legislation" class="boxed">
|
||||||
{{ legislation.text }}
|
<table>
|
||||||
</blockquote>
|
{% for line in lines %}
|
||||||
|
<tr>
|
||||||
|
<td class="legnumbers">{{ line.linenumber }}</td>
|
||||||
|
<td>{{ line.linetext }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
||||||
|
|
|
@ -4,5 +4,6 @@ from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", views.index, name="index"),
|
path("", views.index, name="index"),
|
||||||
|
path("all/", views.all, name="all"),
|
||||||
path("legislation/<int:legislation_id>/", views.view_legislation, name="viewleg"),
|
path("legislation/<int:legislation_id>/", views.view_legislation, name="viewleg"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,16 +3,27 @@ from django.http import HttpResponse
|
||||||
|
|
||||||
from .models import LegislativeText, LegislationBook
|
from .models import LegislativeText, LegislationBook
|
||||||
|
|
||||||
|
from random import sample
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
legislative_texts = LegislativeText.objects.all()
|
legislative_texts = list(LegislativeText.objects.all())
|
||||||
|
legislative_texts = sample(legislative_texts, 5)
|
||||||
context = {
|
context = {
|
||||||
"legislative_texts": legislative_texts,
|
"legislative_texts": legislative_texts,
|
||||||
}
|
}
|
||||||
return render(request, "explorer/index.html", context)
|
return render(request, "explorer/index.html", context)
|
||||||
|
|
||||||
|
def all(request):
|
||||||
|
legislative_texts = list(LegislativeText.objects.all())
|
||||||
|
context = {
|
||||||
|
"legislative_texts": legislative_texts,
|
||||||
|
}
|
||||||
|
return render(request, "explorer/all.html", context)
|
||||||
|
|
||||||
def view_legislation(request, legislation_id):
|
def view_legislation(request, legislation_id):
|
||||||
legislation = get_object_or_404(LegislativeText, pk=legislation_id)
|
legislation = get_object_or_404(LegislativeText, pk=legislation_id)
|
||||||
context = {
|
context = {
|
||||||
"legislation": legislation,
|
"legislation": legislation,
|
||||||
|
"lines": legislation.get_lines()
|
||||||
}
|
}
|
||||||
return render(request, "explorer/legislation.html", context)
|
return render(request, "explorer/legislation.html", context)
|
||||||
|
|
|
@ -15,7 +15,6 @@ from pathlib import Path
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
# Quick-start development settings - unsuitable for production
|
||||||
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
|
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
|
||||||
|
|
||||||
|
@ -25,8 +24,7 @@ SECRET_KEY = 'django-insecure-1%p#re)z*_xd9umo0!1foh(yiz&2=*5q#0b4(m42r0^m%kxli#
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
ALLOWED_HOSTS = []
|
ALLOWED_HOSTS = ["localhost", "127.0.0.1", "[::1]"]
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
|
|
||||||
|
@ -81,6 +79,9 @@ DATABASES = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATICFILES_DIRS = [
|
||||||
|
BASE_DIR / "static",
|
||||||
|
]
|
||||||
|
|
||||||
# Password validation
|
# Password validation
|
||||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
|
||||||
|
@ -100,7 +101,6 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/4.2/topics/i18n/
|
# https://docs.djangoproject.com/en/4.2/topics/i18n/
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ USE_TZ = True
|
||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/4.2/howto/static-files/
|
# https://docs.djangoproject.com/en/4.2/howto/static-files/
|
||||||
|
|
||||||
STATIC_URL = 'static/'
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
# Default primary key field type
|
# Default primary key field type
|
||||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
||||||
|
|
|
@ -16,8 +16,10 @@ Including another URLconf
|
||||||
"""
|
"""
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
|
from django.conf import settings
|
||||||
|
from django.conf.urls.static import static
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('explorer/', include("explorer.urls")),
|
path('explorer/', include("explorer.urls")),
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
]
|
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
django
|
||||||
|
pymupdf
|
||||||
|
gunicorn
|
|
@ -0,0 +1,79 @@
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav#navbar {
|
||||||
|
border-bottom: 1px solid black; /* block for top bar */
|
||||||
|
padding-bottom: 10px;
|
||||||
|
display: flex; /* make it from left to right */
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
#leftnav {
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rightnav {
|
||||||
|
padding-left: 10px;
|
||||||
|
|
||||||
|
/* make this part right justified */
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#legcontainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#leginfo {
|
||||||
|
width: 15em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#legislation {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 280px) {
|
||||||
|
#rightnav {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 570px) {
|
||||||
|
#legcontainer {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
#leginfo {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-margin-top {
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxed {
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
padding-top: 0px;
|
||||||
|
border: solid 1px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapword {
|
||||||
|
white-space: -moz-pre-wrap !important;
|
||||||
|
white-space: -pre-wrap;
|
||||||
|
white-space: -o-pre-wrap;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
white-space: -webkit-pre-wrap;
|
||||||
|
word-break: break-all;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legnumbers {
|
||||||
|
text-align: right;
|
||||||
|
user-select: none;
|
||||||
|
}
|
Loading…
Reference in New Issue