Skip to content

Commit 192d4cf

Browse files
authored
Merge pull request #1810 from codeforpdx/manual-page-updates
Manual Page Updates
2 parents bc93845 + 3fab204 commit 192d4cf

30 files changed

+1956
-698
lines changed

scripts/generate-checklist-pdf.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
"""
2+
Generate the RecordSponge Expungement Checklist PDF.
3+
4+
Requirements: pip install reportlab
5+
6+
Output: src/frontend/public/docs/expungement-checklist.pdf
7+
8+
Run from the project root:
9+
python scripts/generate-checklist-pdf.py
10+
"""
11+
12+
import os
13+
from reportlab.lib.pagesizes import letter
14+
from reportlab.lib.units import inch
15+
from reportlab.lib.colors import HexColor, black, white
16+
from reportlab.platypus import (
17+
SimpleDocTemplate, Paragraph, Spacer, HRFlowable, Flowable
18+
)
19+
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
20+
21+
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
22+
OUTPUT_PATH = os.path.join(SCRIPT_DIR, "..", "src", "frontend", "public", "docs", "expungement-checklist.pdf")
23+
24+
25+
class CheckboxStep(Flowable):
26+
"""A checkbox followed by step text, vertically aligned."""
27+
28+
def __init__(self, text, style, checkbox_size=11):
29+
super().__init__()
30+
self.text = text
31+
self.style = style
32+
self.checkbox_size = checkbox_size
33+
self._para = Paragraph(text, style)
34+
35+
def wrap(self, availWidth, availHeight):
36+
text_width = availWidth - self.checkbox_size - 10
37+
self._para_w, self._para_h = self._para.wrap(text_width, availHeight)
38+
self.width = availWidth
39+
self.height = self._para_h + 4
40+
return self.width, self.height
41+
42+
def draw(self):
43+
para_y = self.height - self._para_h
44+
self._para.drawOn(self.canv, self.checkbox_size + 10, para_y)
45+
46+
cb_y = self.height - self._para_h + (self._para_h - self.checkbox_size) / 2 - 1
47+
48+
self.canv.setStrokeColor(black)
49+
self.canv.setFillColor(white)
50+
self.canv.setLineWidth(0.8)
51+
self.canv.rect(0, max(0, cb_y), self.checkbox_size, self.checkbox_size, fill=1, stroke=1)
52+
53+
54+
def generate():
55+
os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True)
56+
57+
doc = SimpleDocTemplate(
58+
OUTPUT_PATH,
59+
pagesize=letter,
60+
topMargin=0.75 * inch,
61+
bottomMargin=0.75 * inch,
62+
leftMargin=0.75 * inch,
63+
rightMargin=0.75 * inch,
64+
)
65+
66+
styles = getSampleStyleSheet()
67+
blue = HexColor("#357edd")
68+
dark = HexColor("#333333")
69+
gray = HexColor("#555555")
70+
71+
title_style = ParagraphStyle("ChecklistTitle", parent=styles["Title"], fontSize=20, textColor=dark, spaceAfter=6)
72+
subtitle_style = ParagraphStyle("Subtitle", parent=styles["Normal"], fontSize=11, textColor=gray, spaceAfter=4)
73+
step_style = ParagraphStyle("StepStyle", parent=styles["Normal"], fontSize=12, textColor=dark, fontName="Helvetica-Bold", spaceBefore=0, spaceAfter=4, leading=14)
74+
sub_style = ParagraphStyle("SubStyle", parent=styles["Normal"], fontSize=11, textColor=gray, leftIndent=28, spaceBefore=2, spaceAfter=2)
75+
note_style = ParagraphStyle("NoteStyle", parent=styles["Normal"], fontSize=11, textColor=gray, spaceBefore=0, spaceAfter=4, borderWidth=1, borderColor=HexColor("#cccccc"), borderPadding=8)
76+
77+
link_str = 'color="#357edd"'
78+
story = []
79+
80+
story.append(Paragraph("RecordSponge Expungement Checklist", title_style))
81+
story.append(Paragraph("A step-by-step guide to the expungement process", subtitle_style))
82+
story.append(HRFlowable(width="100%", thickness=1, color=blue, spaceAfter=12))
83+
84+
steps = [
85+
{
86+
"title": "Log in to OECI",
87+
"subs": [
88+
"You will need an OECI account to search for criminal records.",
89+
f'Purchase a subscription at <a href="https://www.courts.oregon.gov/services/online/Pages/ojcin-signup.aspx" {link_str}>courts.oregon.gov</a>.',
90+
],
91+
},
92+
{
93+
"title": "Search records",
94+
"subs": [
95+
"Ensure that Assumptions are met",
96+
"Search by name and date of birth",
97+
],
98+
},
99+
{
100+
"title": "Complete paperwork for expungement",
101+
"subs": [
102+
"This includes paperwork to modify financial obligations if applicable",
103+
],
104+
},
105+
{
106+
"title": "Obtain fingerprints",
107+
"subs": [
108+
"Mail to Oregon State Police",
109+
],
110+
},
111+
{
112+
"title": "File paperwork in appropriate courts",
113+
"subs": [],
114+
},
115+
]
116+
117+
for i, step in enumerate(steps, 1):
118+
story.append(Spacer(1, 10))
119+
story.append(CheckboxStep(f'<b>Step {i}:</b> {step["title"]}', step_style))
120+
for sub in step["subs"]:
121+
story.append(Paragraph(f"\u2022 {sub}", sub_style))
122+
123+
story.append(Spacer(1, 24))
124+
story.append(Paragraph(
125+
f'<b>Note:</b> If new to RecordSponge, confirm results with Michael Zhang at '
126+
f'<a href="mailto:michael@qiu-qiulaw.com" {link_str}>michael@qiu-qiulaw.com</a>.<br/><br/>'
127+
f'For further details, visit <a href="https://recordsponge.com/manual" {link_str}>recordsponge.com/manual</a>.',
128+
note_style,
129+
))
130+
131+
doc.build(story)
132+
print(f"PDF generated: {os.path.abspath(OUTPUT_PATH)}")
133+
134+
135+
if __name__ == "__main__":
136+
generate()
2.44 KB
Binary file not shown.
24.5 KB
Loading
28.9 KB
Loading
47.4 KB
Loading
126 KB
Loading
68.9 KB
Loading
6.99 KB
Loading
9.59 KB
Loading
19.6 KB
Loading

0 commit comments

Comments
 (0)