Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Development to Main to close Issues #119

Merged
merged 83 commits into from
Sep 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
f38ced9
Script to convert NIST EDF data into BallotLab data.
ion-oset Aug 21, 2022
88aa5bc
First pass at candidate contests.
ion-oset Aug 21, 2022
41e188c
Ordered content includes headers; use argparse.
ion-oset Aug 21, 2022
25ff3cf
Flags for keeping write-ins, n-of-m contests.
ion-oset Aug 21, 2022
584bb41
Drop 'keep' flags, add '--debug' for exceptions, more doc comments.
ion-oset Aug 21, 2022
43eb184
Significant refactoring of candidate contests.
ion-oset Aug 21, 2022
24b921f
Add offices and parties to candidate contests.
ion-oset Aug 21, 2022
9f0ab55
Add ballot measure contests.
ion-oset Aug 21, 2022
f1fd991
Add ballot text; don't return offices or parties for candidates.
ion-oset Aug 21, 2022
309db0e
Add README for ballot-lab-data script.
ion-oset Aug 22, 2022
f5090b8
Add party names to candidates.
ion-oset Aug 22, 2022
55b5b38
Add votes allowed on candidates races (even if it's the default).
ion-oset Aug 23, 2022
a262592
Add party abbreviations to candidates.
ion-oset Aug 23, 2022
4a27316
Include '@id's with contests.
ion-oset Aug 23, 2022
15efb15
Use 'ContestSelectionId's instead of a count for write-ins.
ion-oset Aug 23, 2022
4355de7
Add selection IDs to all candidates, not just write-ins.
ion-oset Aug 24, 2022
26deeaf
Properly set up multi-candidate slates/tickets.
ion-oset Aug 24, 2022
fb03e3f
Merge write-ins into candidte contests.
ion-oset Aug 24, 2022
1547160
Multi-candidate slates: Fix dropping all candidates before the last one.
ion-oset Aug 27, 2022
78f933a
Multi-candidate slates: Use party IDs to collapse identical parties.
ion-oset Aug 27, 2022
e658646
Multi-candidate slates: Only collapse party IDs if ALL parties are id…
ion-oset Aug 27, 2022
d48ddf7
Drop null fields of parties; use an empty dictionary if a party is mi…
ion-oset Aug 27, 2022
4d1bfb4
Add IDs to ballot measures contests.
ion-oset Aug 27, 2022
8fd9337
Add IDs to ballot measure contest selections.
ion-oset Aug 29, 2022
6a88c50
Update README for 'ballot-lab-data' script.
ion-oset Aug 30, 2022
db0773e
Update of JSON ballot generator.
ion-oset Sep 5, 2022
fb195a0
Update Spacetown data to match generator updates.
ion-oset Sep 5, 2022
fe81fbc
Use September test case for Spacetown data.
ion-oset Sep 5, 2022
818f21b
Update the internal Spacetown data to use the September test case.
ion-oset Sep 5, 2022
9b91232
Switch to human readable IDs.
ion-oset Sep 6, 2022
983ff88
Clean up docstrings
stratofax Sep 7, 2022
7b88323
Merge pull request #106 from ion-oset/september-ballot
ion-oset Sep 8, 2022
b3f1cb2
Add ballot data for remaining jurisdictions in September test case.
ion-oset Sep 7, 2022
929a4be
Merge branch 'development' into 'edf-to-ballot-data'.
ion-oset Sep 9, 2022
827b2c9
Move 'scripts' to 'data' and rename script.
ion-oset Sep 9, 2022
8d6d431
Separate EDF to data into a script and a module.
ion-oset Sep 9, 2022
2bec0c1
Use explicit EDF model imports ballot data extractor.
ion-oset Sep 9, 2022
05fac8f
Simplify naming of ballot data extractor functions.
ion-oset Sep 9, 2022
67d3933
Data model for ballot measure choices.
ion-oset Sep 9, 2022
9921c2d
Data model for ballot measure contests.
ion-oset Sep 10, 2022
4e7283f
Data model for candidate parties.
ion-oset Sep 10, 2022
e099419
Data model for candidate choices.
ion-oset Sep 10, 2022
5dc5ca8
Data model for candidate contests.
ion-oset Sep 10, 2022
a112e03
Simplify test assertions on nested data by comparing dictionaries.
ion-oset Sep 12, 2022
7873833
Data model for ballot styles.
ion-oset Sep 12, 2022
3621f32
Data model for elections.
ion-oset Sep 12, 2022
893af78
Use a base type for contest models.
ion-oset Sep 12, 2022
df0a193
Add class override for buttonFieldRelative
stratofax Sep 12, 2022
e03c3bb
Add derived candidate and ballot measure contest properties for ballo…
ion-oset Sep 12, 2022
a7f19c1
Reorder contest fields in ballot data extractor to match ballot data …
ion-oset Sep 12, 2022
341df82
Don't return an empty party dictionary when there is no party.
ion-oset Sep 12, 2022
002e415
Re-combine candidate and ballot measure contests in extractor.
ion-oset Sep 13, 2022
3059297
Add IDs to PDF form
stratofax Sep 13, 2022
da218db
Replace magic numbers with constants
stratofax Sep 13, 2022
b173842
Re-implement and simplify the ballot extractor interface.
ion-oset Sep 14, 2022
5ace8d6
Move document and index creation into 'report'.
ion-oset Sep 14, 2022
04e0d3e
Make 'ElectionReport' and 'ElementIndex' internal to the extractor.
ion-oset Sep 14, 2022
5350723
Document the entry point of the extractor API.
ion-oset Sep 14, 2022
7e2f748
Turn ballot extractor into a class.
ion-oset Sep 14, 2022
1195709
Rename extractor internal functions start with '_extract'.
ion-oset Sep 14, 2022
cf945d5
Update comments
stratofax Sep 14, 2022
4b4b728
Test ballot generation on Linux
stratofax Sep 14, 2022
0e9de74
Hide form objects
stratofax Sep 14, 2022
358bffd
Sample code and demo PDFs for testing
stratofax Sep 14, 2022
9611b08
Test ballots with white ovals
stratofax Sep 14, 2022
2ba1c0e
Merge pull request #112 from ion-oset/edf-to-ballot-data to development
stratofax Sep 15, 2022
1e5b7ff
Add September data to assets
stratofax Sep 15, 2022
35597ea
Update validate subcommand to use data extractor
stratofax Sep 15, 2022
f55562a
Update validation, test ElectionData class
stratofax Sep 15, 2022
92e9477
Add comments with Errors
stratofax Sep 15, 2022
7d130ff
New ballot builder code
stratofax Sep 15, 2022
850f6e5
Disable tests for validate command
stratofax Sep 16, 2022
2d1221d
Generate 4 demo ballots with headers
stratofax Sep 16, 2022
aa643a2
updated scopes extraction
stratofax Sep 16, 2022
d9eccfc
Generate 4 ballots
stratofax Sep 17, 2022
52da16e
Update CLI to run demo
stratofax Sep 17, 2022
13da497
First round of code cleanup
stratofax Sep 18, 2022
12a2380
Code cleanup and comments
stratofax Sep 18, 2022
5a3a03e
Hide widgets, remove unused data class
stratofax Sep 18, 2022
12196c1
Add TODOs and backlinks
stratofax Sep 20, 2022
b2c7092
Merge pull request #113 from stratofax/development
stratofax Sep 20, 2022
2cfd38d
Increment version number and CHANGELOG to close Milestone 2 (#118)
stratofax Sep 22, 2022
45f06ba
Remove test output PDF from repo root
stratofax Sep 22, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@

A version history of BallotLab.

## 0.1.3 - September 20, 2022

Completed [Milestone 2. Generate ballot PDFs with embedded form objects Milestone](https://github.com/TrustTheVote-Project/BallotLab/milestone/2)

* Prototype check boxes to track coordinates of vote marking ovals
* Generate ballots with hidden, embedded form objects to track coordinates and ids of vote mark ovals
* Generate ballots from all four (4) precincts in the September 2022 EDF
* Incorporate new NISTLib data access layer (includes corresponding test harness)
* Additional layout enhancements and refinements

## 0.1.2 - September 7, 2022

Complete Milestone 1: flat file PDF. Notable features include:
Completed milestone 1: [Generate flat PDFs from Jetsons EDF](https://github.com/TrustTheVote-Project/BallotLab/milestone/1)

* Multi-candidate tickets (including contest section IDs)
* Write-ins (also with contest selection IDs)
Expand Down
Binary file added pdfs/ballot_demo_2022_09_13T095513.pdf
Binary file not shown.
Binary file added pdfs/precinct_2_spacetown.pdf
Binary file not shown.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "BallotMaker"
version = "0.1.1"
version = "0.1.3"
description = "Generate PDF ballots from EDF file; part of ElectOS Versa."
authors = ["Neil Johnson <[email protected]>"]
license = "OSET Public License"
Expand Down
9 changes: 9 additions & 0 deletions samplecode/form_reader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import PyPDF2 as pypdf

pdfobject = open(
"/Users/neil/repos/BallotLabFork/samplecode/ballot_demo_2022_09_13T095513.pdf",
"rb",
)
pdf = pypdf.PdfFileReader(pdfobject)
form_data = pdf.get_fields()
print(form_data)
79 changes: 79 additions & 0 deletions samplecode/form_table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# from https://groups.google.com/g/reportlab-users/c/KRx3oLi34Dc/m/3GGnhy3qCQAJ
# import PyPDF2
from reportlab.pdfbase import pdfform
from reportlab.platypus import Flowable, SimpleDocTemplate, Table

# from pprint import pprint


class formCheckButton(Flowable):
def __init__(self, title, value="Yes"):
self.title = title
self.value = value
self.width = 16
self.height = 16

def wrap(self, *args):
self.width = args[0]
return (self.width, self.height)

def draw(self):
self.canv.saveState()
pdfform.buttonFieldRelative(
self.canv,
self.title,
self.value,
0,
0,
# including w & h shift the buttons up
# width=self.width,
# height=self.height,
)
self.canv.restoreState()


class formInputField(Flowable):
def __init__(self, id, value="Sample"):
self.id = id
self.value = value
self.width = 0
self.height = 10

def wrap(self, *args):
self.width = args[0]
return (self.width, self.height)

def draw(self):
self.canv.saveState()
pdfform.textFieldRelative(self.canv, self.id, 0, 0, 50, 10, self.value)
self.canv.restoreState()


class createExamplePDFFormFile:
def __init__(self, filename):
data = []
value = "Yes"
for i in range(10):
title = f"title {i}"
checkbox = formCheckButton(title, value)
data.append([title, checkbox])
dataTable = Table(data)
print([dataTable])
doc = SimpleDocTemplate(filename)
doc.build([dataTable])


# class readExamplePDFFormFile:
# def __init__(self, filename):
# f = PyPDF2.PdfFileReader(filename)
# data = f.getFields()
# for title, value in data.items():
# pprint(value)


ORIGINAL_FILE = "OriginalFile.pdf"
EDITED_FILE = "EditedFile.pdf"

createExamplePDFFormFile(ORIGINAL_FILE)
# readExamplePDFFormFile(ORIGINAL_FILE)
# readExamplePDFFormFile(EDITED_FILE)
Loading