Compare commits
4 Commits
10dd6418b7
...
308b0f978f
Author | SHA1 | Date |
---|---|---|
stupidcomputer | 308b0f978f | |
stupidcomputer | 3c73c209a7 | |
stupidcomputer | c08636fcad | |
stupidcomputer | 244c71eb59 |
|
@ -0,0 +1,7 @@
|
|||
*.log
|
||||
*.pot
|
||||
*.pyc
|
||||
__pycache__
|
||||
db.sqlite3
|
||||
media
|
||||
uploads/
|
|
@ -0,0 +1,4 @@
|
|||
yig
|
||||
===
|
||||
|
||||
A tool to explore past bills, manage delegations, etc.
|
|
@ -0,0 +1,6 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from .models import LegislativeText, LegislationBook
|
||||
|
||||
admin.site.register(LegislativeText)
|
||||
admin.site.register(LegislationBook)
|
|
@ -0,0 +1,6 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ExplorerConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'explorer'
|
|
@ -0,0 +1,39 @@
|
|||
# Generated by Django 4.2.12 on 2024-06-19 06:53
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='LegislationBook',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('conference_type', models.CharField(choices=[('M', 'Middle School'), ('H', 'High School')], default='H', max_length=1)),
|
||||
('pdf', models.FileField(upload_to='uploads/')),
|
||||
('name', models.CharField(max_length=256)),
|
||||
('import_strategy', models.CharField(max_length=128)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LegislativeText',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('assembly', models.CharField(choices=[('RGA', 'Red General Assembly'), ('BGA', 'Blue General Assembly'), ('WGA', 'White General Assembly'), ('RHB', 'Red House'), ('BHB', 'Blue House'), ('WHB', 'White House'), ('RSB', 'Red Senate'), ('BSB', 'Blue Senate'), ('WSB', 'White Senate'), ('SEN', 'Senate'), ('HOU', 'House'), ('GEN', 'General Assembly')], default='GEN', max_length=3)),
|
||||
('text', models.TextField()),
|
||||
('year', models.IntegerField()),
|
||||
('committee', models.IntegerField()),
|
||||
('docket_order', models.IntegerField()),
|
||||
('school', models.CharField(max_length=256)),
|
||||
('sponsors', models.CharField(max_length=256)),
|
||||
('from_book', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='explorer.legislationbook')),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 4.2.12 on 2024-06-19 07:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('explorer', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='legislativetext',
|
||||
name='legislation_title',
|
||||
field=models.CharField(default='Sample title', max_length=512),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -0,0 +1,55 @@
|
|||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class LegislationBook(models.Model):
|
||||
class ConferenceType(models.TextChoices):
|
||||
MIDDLE = "M", _("Middle School")
|
||||
HIGH = "H", _("High School")
|
||||
|
||||
conference_type = models.CharField(
|
||||
max_length=1,
|
||||
choices=ConferenceType.choices,
|
||||
default=ConferenceType.HIGH,
|
||||
)
|
||||
pdf = models.FileField(upload_to="uploads/")
|
||||
name = models.CharField(max_length=256)
|
||||
import_strategy = models.CharField(max_length=128)
|
||||
|
||||
def __str__(self):
|
||||
return "{}".format(self.name)
|
||||
|
||||
class LegislativeText(models.Model):
|
||||
class Assemblies(models.TextChoices):
|
||||
RGA = "RGA", _("Red General Assembly")
|
||||
BGA = "BGA", _("Blue General Assembly")
|
||||
WGA = "WGA", _("White General Assembly")
|
||||
RHB = "RHB", _("Red House")
|
||||
BHB = "BHB", _("Blue House")
|
||||
WHB = "WHB", _("White House")
|
||||
RSB = "RSB", _("Red Senate")
|
||||
BSB = "BSB", _("Blue Senate")
|
||||
WSB = "WSB", _("White Senate")
|
||||
SEN = "SEN", _("Senate")
|
||||
HOU = "HOU", _("House")
|
||||
GEN = "GEN", _("General Assembly")
|
||||
|
||||
assembly = models.CharField(
|
||||
max_length=3,
|
||||
choices=Assemblies.choices,
|
||||
default=Assemblies.GEN
|
||||
)
|
||||
text = models.TextField()
|
||||
year = models.IntegerField()
|
||||
committee = models.IntegerField()
|
||||
docket_order = models.IntegerField()
|
||||
school = models.CharField(max_length=256)
|
||||
sponsors = models.CharField(max_length=256)
|
||||
from_book = models.ForeignKey(LegislationBook, on_delete=models.CASCADE)
|
||||
legislation_title = models.CharField(max_length=512)
|
||||
|
||||
def __str__(self):
|
||||
return "{}/{}-{}".format(
|
||||
self.assembly,
|
||||
self.committee,
|
||||
self.docket_order,
|
||||
)
|
|
@ -0,0 +1,10 @@
|
|||
<form action="{% url 'import_books' %}" method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<input type="text" name="bookname">
|
||||
<input type="file" name="bookpdf">
|
||||
<input type="submit" value="Import PDF">
|
||||
</form>
|
||||
|
||||
{% if just_imported %}
|
||||
thanks for the import!
|
||||
{% endif %}
|
|
@ -0,0 +1,9 @@
|
|||
{% 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 %}
|
|
@ -0,0 +1,9 @@
|
|||
<h1>{{ legislation.legislation_title }}</h1>
|
||||
|
||||
<i>{{ legislation.assembly }}/{{ legislation.committee }}/{{ legislation.docket_order }}</i>
|
||||
|
||||
<p>Sponsored by {{ legislation.sponsors }} of {{ legislation.school }}</p>
|
||||
|
||||
<blockquote>
|
||||
{{ legislation.text }}
|
||||
</blockquote>
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
|
@ -0,0 +1,9 @@
|
|||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path("", views.index, name="index"),
|
||||
path("legislation/<int:legislation_id>/", views.view_legislation, name="viewleg"),
|
||||
path("import/", views.import_books, name="import_books"),
|
||||
]
|
|
@ -0,0 +1,30 @@
|
|||
from django.shortcuts import get_object_or_404, render
|
||||
from django.http import HttpResponse
|
||||
|
||||
from .models import LegislativeText, LegislationBook
|
||||
|
||||
def index(request):
|
||||
legislative_texts = LegislativeText.objects.all()[:5]
|
||||
context = {
|
||||
"legislative_texts": legislative_texts,
|
||||
}
|
||||
return render(request, "explorer/index.html", context)
|
||||
|
||||
def import_books(request):
|
||||
if request.method == "GET":
|
||||
return render(request, "explorer/import.html", {})
|
||||
elif request.method == "POST":
|
||||
book = LegislationBook(
|
||||
pdf=request.FILES["bookpdf"],
|
||||
name=request.POST.get("bookname"),
|
||||
conference_type="H",
|
||||
)
|
||||
book.save()
|
||||
return render(request, "explorer/import.html", {just_imported: True})
|
||||
|
||||
def view_legislation(request, legislation_id):
|
||||
legislation = get_object_or_404(LegislativeText, pk=legislation_id)
|
||||
context = {
|
||||
"legislation": legislation,
|
||||
}
|
||||
return render(request, "explorer/legislation.html", context)
|
|
@ -0,0 +1,16 @@
|
|||
"""
|
||||
ASGI config for franklincce project.
|
||||
|
||||
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'franklincce.settings')
|
||||
|
||||
application = get_asgi_application()
|
|
@ -0,0 +1,124 @@
|
|||
"""
|
||||
Django settings for franklincce project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 4.2.12.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/4.2/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/4.2/ref/settings/
|
||||
"""
|
||||
|
||||
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/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
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 = []
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'explorer.apps.ExplorerConfig',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'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',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'franklincce.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'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 = 'franklincce.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': BASE_DIR / 'db.sqlite3',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/4.2/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/4.2/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/4.2/howto/static-files/
|
||||
|
||||
STATIC_URL = 'static/'
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
URL configuration for franklincce project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/4.2/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import include, path
|
||||
|
||||
urlpatterns = [
|
||||
path('explorer/', include("explorer.urls")),
|
||||
path('admin/', admin.site.urls),
|
||||
]
|
|
@ -0,0 +1,16 @@
|
|||
"""
|
||||
WSGI config for franklincce 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/4.2/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'franklincce.settings')
|
||||
|
||||
application = get_wsgi_application()
|
|
@ -0,0 +1,22 @@
|
|||
#!/nix/store/7hnr99nxrd2aw6lghybqdmkckq60j6l9-python3-3.11.9/bin/python
|
||||
"""Django's command-line utility for administrative tasks."""
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
"""Run administrative tasks."""
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'franklincce.settings')
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError as exc:
|
||||
raise ImportError(
|
||||
"Couldn't import Django. Are you sure it's installed and "
|
||||
"available on your PYTHONPATH environment variable? Did you "
|
||||
"forget to activate a virtual environment?"
|
||||
) from exc
|
||||
execute_from_command_line(sys.argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue