it's a web interface
This commit is contained in:
parent
9680a416da
commit
3848e1f777
|
@ -0,0 +1,99 @@
|
||||||
|
import secrets
|
||||||
|
|
||||||
|
from flask import Flask
|
||||||
|
from flask import render_template
|
||||||
|
from flask_bootstrap import Bootstrap
|
||||||
|
|
||||||
|
from .leglib.billdb import BillDB, BillQuery, QueryField, QueryAll
|
||||||
|
from .leglib.parsers import HSYIGPdfParser
|
||||||
|
|
||||||
|
parser = HSYIGPdfParser.from_filename(
|
||||||
|
filename="YIGVolunteerBook2024.pdf",
|
||||||
|
confname="HSVolunteer"
|
||||||
|
)
|
||||||
|
parser.parse()
|
||||||
|
db = BillDB()
|
||||||
|
db.add_conference(parser=parser)
|
||||||
|
|
||||||
|
def create_app(test_config=None):
|
||||||
|
app = Flask(__name__, instance_relative_config=True)
|
||||||
|
app.config.from_mapping(
|
||||||
|
SECRET_KEY=str(secrets.randbelow(100000000))
|
||||||
|
)
|
||||||
|
|
||||||
|
Bootstrap(app)
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
bills = db.search(query=QueryAll)
|
||||||
|
return render_template('index.html', number_bills=len(bills), number_conferences=2, bills=bills)
|
||||||
|
|
||||||
|
@app.route('/legislation/<conference>/<year>')
|
||||||
|
def show_conference(conference=QueryField.Any):
|
||||||
|
return conference
|
||||||
|
|
||||||
|
@app.route('/legislation/<conference>/<color>/<year>')
|
||||||
|
def show_color(
|
||||||
|
conference=QueryField.Any,
|
||||||
|
year=QueryField.Any,
|
||||||
|
color=QueryField.Any,
|
||||||
|
):
|
||||||
|
bills = db.search(query=BillQuery(
|
||||||
|
color=color,
|
||||||
|
year=int(year),
|
||||||
|
))
|
||||||
|
return render_template('color.html', bills=bills)
|
||||||
|
|
||||||
|
@app.route('/legislation/<conference>/<color>/<assembly>/<year>')
|
||||||
|
def show_assembly(
|
||||||
|
conference=QueryField.Any,
|
||||||
|
assembly=QueryField.Any,
|
||||||
|
color=QueryField.Any,
|
||||||
|
year=QueryField.Any,
|
||||||
|
):
|
||||||
|
bills = db.search(query=BillQuery(
|
||||||
|
color=color,
|
||||||
|
assembly=assembly,
|
||||||
|
year=int(year),
|
||||||
|
))
|
||||||
|
return render_template('assembly.html', bills=bills)
|
||||||
|
|
||||||
|
@app.route('/legislation/<conference>/<color>/<assembly>/<year>/<committee>')
|
||||||
|
def show_committee(
|
||||||
|
conference=QueryField.Any,
|
||||||
|
assembly=QueryField.Any,
|
||||||
|
color=QueryField.Any,
|
||||||
|
year=QueryField.Any,
|
||||||
|
committee=QueryField.Any,
|
||||||
|
):
|
||||||
|
bills = db.search(query=BillQuery(
|
||||||
|
color=QueryField.Any,
|
||||||
|
assembly=assembly,
|
||||||
|
year=int(year),
|
||||||
|
committee=int(committee),
|
||||||
|
))
|
||||||
|
|
||||||
|
return render_template('committee.html', bills=bills)
|
||||||
|
|
||||||
|
@app.route('/legislation/<conference>/<color>/<assembly>/<year>/<committee>/<order>')
|
||||||
|
def show_bill(
|
||||||
|
conference=QueryField.Any,
|
||||||
|
assembly=QueryField.Any,
|
||||||
|
color=QueryField.Any,
|
||||||
|
year=QueryField.Any,
|
||||||
|
committee=QueryField.Any,
|
||||||
|
order=QueryField.Any,
|
||||||
|
):
|
||||||
|
print(order, int(order))
|
||||||
|
print(color, assembly, year, committee, order)
|
||||||
|
bills = db.search(query=BillQuery(
|
||||||
|
color=color,
|
||||||
|
assembly=assembly,
|
||||||
|
year=int(year),
|
||||||
|
committee=int(committee),
|
||||||
|
order=int(order),
|
||||||
|
))
|
||||||
|
|
||||||
|
return render_template("bill.html", bill=bills[0])
|
||||||
|
|
||||||
|
return app
|
|
@ -1,4 +1,3 @@
|
||||||
import leglib #billdb import BillDB, BillQuery, QueryField, QueryAll
|
|
||||||
from leglib.billdb import BillDB, BillQuery, QueryField, QueryAll
|
from leglib.billdb import BillDB, BillQuery, QueryField, QueryAll
|
||||||
from leglib.parsers import HSYIGPdfParser
|
from leglib.parsers import HSYIGPdfParser
|
||||||
|
|
|
@ -26,10 +26,11 @@ class BillQuery:
|
||||||
"""
|
"""
|
||||||
Holds a query for the BillDB.
|
Holds a query for the BillDB.
|
||||||
"""
|
"""
|
||||||
color: CCEColors | QueryField = QueryField.Any
|
color: str | CCEColors | QueryField = QueryField.Any
|
||||||
assembly: CCEAssemblies | QueryField = QueryField.Any
|
assembly: str | CCEAssemblies | QueryField = QueryField.Any
|
||||||
committee: int | QueryField = QueryField.Any
|
committee: int | QueryField = QueryField.Any
|
||||||
year: int | QueryField = QueryField.Any
|
year: int | QueryField = QueryField.Any
|
||||||
|
order: int | QueryField = QueryField.Any
|
||||||
subcommittee: str | QueryField = QueryField.Any
|
subcommittee: str | QueryField = QueryField.Any
|
||||||
sponsors: str | QueryField = QueryField.Any
|
sponsors: str | QueryField = QueryField.Any
|
||||||
school: str | QueryField = QueryField.Any
|
school: str | QueryField = QueryField.Any
|
||||||
|
@ -98,6 +99,7 @@ class BillDB:
|
||||||
results = []
|
results = []
|
||||||
for bill in self.bills:
|
for bill in self.bills:
|
||||||
try:
|
try:
|
||||||
|
# print("debug, q: {}, b: {}".format(str(query.committee), str(bill.code.committee)))
|
||||||
self.code_enum_match(bill, query, "color")
|
self.code_enum_match(bill, query, "color")
|
||||||
self.code_enum_match(bill, query, "assembly")
|
self.code_enum_match(bill, query, "assembly")
|
||||||
|
|
||||||
|
@ -105,6 +107,10 @@ class BillDB:
|
||||||
if not query.committee == bill.code.committee:
|
if not query.committee == bill.code.committee:
|
||||||
raise SearchNotSatisified()
|
raise SearchNotSatisified()
|
||||||
|
|
||||||
|
if not query.order == QueryField.Any:
|
||||||
|
if not query.order == bill.code.docketplacement:
|
||||||
|
raise SearchNotSatisified()
|
||||||
|
|
||||||
if not query.committee == QueryField.Any:
|
if not query.committee == QueryField.Any:
|
||||||
if not query.year == bill.code.year:
|
if not query.year == bill.code.year:
|
||||||
raise SearchNotSatisified()
|
raise SearchNotSatisified()
|
|
@ -87,3 +87,75 @@ class Bill:
|
||||||
@property
|
@property
|
||||||
def bill_text_concat(self):
|
def bill_text_concat(self):
|
||||||
return ''.join(self.bill_text)
|
return ''.join(self.bill_text)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url(self):
|
||||||
|
if self.code.conference:
|
||||||
|
return "/legislation/" + '/'.join([
|
||||||
|
self.code.conference,
|
||||||
|
self.code.color,
|
||||||
|
self.code.assembly,
|
||||||
|
str(self.code.year),
|
||||||
|
str(self.code.committee),
|
||||||
|
str(self.code.docketplacement)
|
||||||
|
])
|
||||||
|
else:
|
||||||
|
return "/legislation/" + '/'.join([
|
||||||
|
"defaultconf",
|
||||||
|
self.code.color,
|
||||||
|
self.code.assembly,
|
||||||
|
str(self.code.year),
|
||||||
|
str(self.code.committee),
|
||||||
|
str(self.code.docketplacement)
|
||||||
|
])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def committee_url(self):
|
||||||
|
if self.code.conference:
|
||||||
|
return "/legislation/" + '/'.join([
|
||||||
|
self.code.conference,
|
||||||
|
self.code.color,
|
||||||
|
self.code.assembly,
|
||||||
|
str(self.code.year),
|
||||||
|
str(self.code.committee)
|
||||||
|
])
|
||||||
|
else:
|
||||||
|
return "/legislation/" + '/'.join([
|
||||||
|
"defaultconf",
|
||||||
|
self.code.color,
|
||||||
|
self.code.assembly,
|
||||||
|
str(self.code.year),
|
||||||
|
str(self.code.committee)
|
||||||
|
])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def assembly_url(self):
|
||||||
|
if self.code.conference:
|
||||||
|
return "/legislation/" + '/'.join([
|
||||||
|
self.code.conference,
|
||||||
|
self.code.color,
|
||||||
|
self.code.assembly,
|
||||||
|
str(self.code.year),
|
||||||
|
])
|
||||||
|
else:
|
||||||
|
return "/legislation/" + '/'.join([
|
||||||
|
"defaultconf",
|
||||||
|
self.code.color,
|
||||||
|
self.code.assembly,
|
||||||
|
str(self.code.year),
|
||||||
|
])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def color_url(self):
|
||||||
|
if self.code.conference:
|
||||||
|
return "/legislation/" + '/'.join([
|
||||||
|
self.code.conference,
|
||||||
|
self.code.color,
|
||||||
|
str(self.code.year),
|
||||||
|
])
|
||||||
|
else:
|
||||||
|
return "/legislation/" + '/'.join([
|
||||||
|
"defaultconf",
|
||||||
|
self.code.color,
|
||||||
|
str(self.code.year),
|
||||||
|
])
|
|
@ -0,0 +1,14 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %} testing title {% endblock %}
|
||||||
|
{% block defcontent %}
|
||||||
|
<h1>{{ bills[0].code.color }} {{ bills[0].code.assembly }}</h1>
|
||||||
|
|
||||||
|
{% for bill in bills %}
|
||||||
|
<div class="container border-black">
|
||||||
|
<a href="{{ bill.url }}">({{bill.code.assembly[0]}}{{bill.code.committee}}/{{bill.code.docketplacement}}) {{ bill.title }}</a>
|
||||||
|
<p>Sponsors: {{ bill.sponsors }}</p>
|
||||||
|
<p>School: {{ bill.school }}</p>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,32 @@
|
||||||
|
{% extends "bootstrap/base.html" %}
|
||||||
|
|
||||||
|
{% block navbar %}
|
||||||
|
<nav class="navbar navbar-default">
|
||||||
|
<a class="navbar-brand" href="/">cceexplorer</a>
|
||||||
|
<div class="navbar-nav" id="navbarNav">
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/search">Search</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/statistics">Statistics</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/conferences">Conferences</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/scores">Scores</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="container-fluid">
|
||||||
|
{% block defcontent %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,28 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %} cceexplorer - {{ bill.title }} {% endblock %}
|
||||||
|
{% block defcontent %}
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-3 border border-dark rounded">
|
||||||
|
<h1>{{ bill.code.stringrep }}</h1>
|
||||||
|
<p><i>{{ bill.title }}</i></p>
|
||||||
|
<p>Introduced by {{ bill.sponsors }} (of {{ bill.school }}) within the {{ bill.subcommittee }} subcommittee</p>
|
||||||
|
<hr>
|
||||||
|
<ul>
|
||||||
|
<li><a href="{{ bill.committee_url }}">Go to this bill's committee</a></li>
|
||||||
|
<li><a href="{{ bill.assembly_url }}">Go to this bill's assembly</a></li>
|
||||||
|
<li><a href="{{ bill.color_url }}">Go to this bill's color grouping</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-7 border border-dark rounded">
|
||||||
|
<br>
|
||||||
|
{% for line in bill.bill_text %}
|
||||||
|
{% if line == "" %}
|
||||||
|
{% endif %}
|
||||||
|
<p>{{ line }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %} testing title {% endblock %}
|
||||||
|
{% block defcontent %}
|
||||||
|
<h1>All {{bills[0].code.color}} Legislation</h1>
|
||||||
|
|
||||||
|
{% for bill in bills %}
|
||||||
|
<div class="container border-black">
|
||||||
|
<a href="{{ bill.url }}">({{bill.code.committee}}/{{bill.code.docketplacement}}) {{ bill.title }}</a>
|
||||||
|
<p>Sponsors: {{ bill.sponsors }}</p>
|
||||||
|
<p>School: {{ bill.school }}</p>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %} testing title {% endblock %}
|
||||||
|
{% block defcontent %}
|
||||||
|
<h1>{{ bills[0].code.assembly }} Committee {{ bills[0].code.committee }}</h1>
|
||||||
|
|
||||||
|
{% for bill in bills %}
|
||||||
|
<div class="container border-black">
|
||||||
|
<a href="{{ bill.url }}">({{bill.code.color}}) {{ bill.title }}</a>
|
||||||
|
<p>Sponsors: {{ bill.sponsors }}</p>
|
||||||
|
<p>School: {{ bill.school }}</p>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %} testing title {% endblock %}
|
||||||
|
{% block defcontent %}
|
||||||
|
<h1>{{ bills[0].code.color }} {{ bills[0].code.assembly }}</h1>
|
||||||
|
|
||||||
|
{% for bill in bills %}
|
||||||
|
<div class="container border-black">
|
||||||
|
<a href="{{ bill.url }}">({{bill.code.assembly[0]}}{{bill.code.committee}}/{{bill.code.docketplacement}}) {{ bill.title }}</a>
|
||||||
|
<p>Sponsors: {{ bill.sponsors }}</p>
|
||||||
|
<p>School: {{ bill.school }}</p>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %} testing title {% endblock %}
|
||||||
|
{% block defcontent %}
|
||||||
|
<h1>Welcome to cceexplorer</h1>
|
||||||
|
<p><i>an interactive database with {{ number_bills }} bills and {{ number_conferences }} conferences</i></p>
|
||||||
|
<p>here's all of them, down here!</p>
|
||||||
|
<ul>
|
||||||
|
{% for bill in bills %}
|
||||||
|
<li>
|
||||||
|
<a href="{{ bill.url }}">{{ bill.title }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %} testing title {% endblock %}
|
||||||
|
{% block defcontent %}
|
||||||
|
<h1>testing</h1>
|
||||||
|
{% endblock %}
|
|
@ -4,5 +4,6 @@
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
buildPackages.python311Packages.pymupdf
|
buildPackages.python311Packages.pymupdf
|
||||||
buildPackages.python311Packages.flask
|
buildPackages.python311Packages.flask
|
||||||
|
buildPackages.python311Packages.flask-bootstrap
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue