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 fitz
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
class LegislationBook(models.Model):
|
||||
class ConferenceType(models.TextChoices):
|
||||
MIDDLE = "M", _("Middle School")
|
||||
|
@ -106,3 +108,7 @@ class LegislativeText(models.Model):
|
|||
self.committee,
|
||||
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 %}
|
||||
<ul>
|
||||
{% for text in legislative_texts %}
|
||||
|
@ -7,3 +16,4 @@
|
|||
{% else %}
|
||||
<p>No texts available</p>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
|
|
|
@ -1,9 +1,24 @@
|
|||
<h1>{{ legislation.legislation_title }}</h1>
|
||||
{% extends "explorer/base.html" %}
|
||||
|
||||
<i>{{ legislation.assembly }}/{{ legislation.committee }}/{{ legislation.docket_order }}</i>
|
||||
{% block content %}
|
||||
<div id="legcontainer">
|
||||
<div id="leginfo" class="boxed">
|
||||
<h1 class="no-margin-top wrapword">{{ legislation.legislation_title }}</h1>
|
||||
|
||||
<p>Sponsored by {{ legislation.sponsors }} of {{ legislation.school }}</p>
|
||||
<i>{{ legislation.assembly }}/{{ legislation.committee }}/{{ legislation.docket_order }}</i>
|
||||
|
||||
<blockquote>
|
||||
{{ legislation.text }}
|
||||
</blockquote>
|
||||
<p>Sponsored by {{ legislation.sponsors }} of {{ legislation.school }}</p>
|
||||
</div>
|
||||
|
||||
<div id="legislation" class="boxed">
|
||||
<table>
|
||||
{% 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 = [
|
||||
path("", views.index, name="index"),
|
||||
path("all/", views.all, name="all"),
|
||||
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 random import sample
|
||||
|
||||
def index(request):
|
||||
legislative_texts = LegislativeText.objects.all()
|
||||
legislative_texts = list(LegislativeText.objects.all())
|
||||
legislative_texts = sample(legislative_texts, 5)
|
||||
context = {
|
||||
"legislative_texts": legislative_texts,
|
||||
}
|
||||
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):
|
||||
legislation = get_object_or_404(LegislativeText, pk=legislation_id)
|
||||
context = {
|
||||
"legislation": legislation,
|
||||
"lines": legislation.get_lines()
|
||||
}
|
||||
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'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# 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!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = []
|
||||
|
||||
ALLOWED_HOSTS = ["localhost", "127.0.0.1", "[::1]"]
|
||||
|
||||
# Application definition
|
||||
|
||||
|
@ -81,6 +79,9 @@ DATABASES = {
|
|||
}
|
||||
}
|
||||
|
||||
STATICFILES_DIRS = [
|
||||
BASE_DIR / "static",
|
||||
]
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
|
||||
|
@ -100,7 +101,6 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||
},
|
||||
]
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/4.2/topics/i18n/
|
||||
|
||||
|
@ -116,7 +116,7 @@ USE_TZ = True
|
|||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/4.2/howto/static-files/
|
||||
|
||||
STATIC_URL = 'static/'
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
# Default primary key field type
|
||||
# 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.urls import include, path
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
|
||||
urlpatterns = [
|
||||
path('explorer/', include("explorer.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