Notes
Notes - notes.io |
def extract_sta_view(request):
"""
Final stable version:
- Regex logic preserved
- YOLO logic preserved
- Controlled merge
"""
context = user_profile_context(request)
history_id = request.GET.get("history_id") or request.POST.get("history_id")
if not history_id:
return render(request, "app/extract_sta.html", {
**context,
"error": "Invalid request. Lighting plan not selected."
})
try:
history = FDOTExportHistory.objects.get(id=history_id, user=request.user)
except FDOTExportHistory.DoesNotExist:
return render(request, "app/extract_sta.html", {
**context,
"error": "Lighting plan not found."
})
pdf_form = PDFFileForm()
pages_output = []
lighting_pages = []
legend_pages = []
pagewise_payitems = {}
fdot_table = None
error = None
# -----------------------------
# WIRE MAP (UNCHANGED)
# -----------------------------
WIRE_PAYITEM_MAP = {
6: "715-1-12",
7: "715-1-12",
8: "715-1-12",
1: "715-1-14",
0: "715-1-14",
10: "715-1-11",
2: "715-1-13",
3: "715-1-13",
4: "715-1-13",
}
if request.method == "POST":
pdf_form = PDFFileForm(request.POST, request.FILES)
if pdf_form.is_valid():
pdf_path = os.path.join(settings.MEDIA_ROOT, "uploaded_sta.pdf")
os.makedirs(settings.MEDIA_ROOT, exist_ok=True)
with open(pdf_path, "wb+") as f:
for chunk in pdf_form.cleaned_data["pdf"].chunks():
f.write(chunk)
try:
# -----------------------------
# Detect lighting pages
# -----------------------------
doc = fitz.open(pdf_path)
for p in range(len(doc)):
lines = [
ln.strip()
for ln in doc.load_page(p).get_text("text").split("n")
if ln.strip()
]
page_text = "n".join(lines)
if is_lighting_page(lines):
lighting_pages.append(p + 1)
if is_legend_page(page_text):
legend_pages.append(p + 1)
lighting_pages = sorted(set(lighting_pages))
if not lighting_pages:
raise Exception("No lighting plan pages found.")
# -----------------------------
# REGEX PAYITEMS (BASE TRUTH)
# -----------------------------
pagewise_payitems = compute_pagewise_payitem_TL(
pdf_path, lighting_pages
)
# -----------------------------
# PAGE PROCESSING (UNCHANGED)
# -----------------------------
for page in lighting_pages:
stas = extract_sta_values_from_page(pdf_path, page)
distances = compute_distances(stas)
run_blocks, total_d, wire_summary = extract_run_blocks_from_page(
pdf_path, page
)
derived_payitems = {}
for wire, lf in wire_summary.items():
pi = WIRE_PAYITEM_MAP.get(wire)
if pi:
derived_payitems[pi] = derived_payitems.get(pi, 0) + lf
run_length_summary = extract_run_length_sum_by_payitem(
pdf_path, page
)
pole_data = extract_pole_records_from_page(pdf_path, page)
poles = pole_data.get("poles", [])
ud_poles = pole_data.get("underdeck_poles", [])
bl_poles = extract_bl_const_poles_from_page(pdf_path, page)
pole_counts = {}
for p_data in poles + ud_poles + bl_poles:
pi = find_payitem_for_pole(
pagewise_payitems.get(page, {"items": []}),
p_data
)
if pi:
pole_counts[pi] = pole_counts.get(pi, 0) + 1
pages_output.append({
"page": page,
"stas": stas,
"distances": distances,
"runs": run_blocks,
"total_d": total_d,
"wire_summary": wire_summary,
"derived_payitems": derived_payitems,
"run_length_summary": run_length_summary,
"poles": poles,
"underdeck_poles": ud_poles,
"bl_const_poles": bl_poles,
"payitems": pagewise_payitems.get(page, {}),
"pole_counts": pole_counts,
})
# -----------------------------
# BUILD FDOT TABLE (REGEX)
# -----------------------------
fdot_table = build_fdot_table_with_poles(
pagewise_payitems, pages_output, lighting_pages
)
# -----------------------------
# RESET TOTALS (IMPORTANT)
# -----------------------------
for row in fdot_table["rows"]:
row["total_plan"] = sum(row["per_page"].values())
# =====================================================
# 🔥 YOLO MERGE (SAFE & ISOLATED)
# =====================================================
all_yolo_results = []
for page in lighting_pages:
all_yolo_results.extend(get_yolo_payitems(pdf_path, page))
row_map = {r["pay_item"]: r for r in fdot_table["rows"]}
# Reset YOLO pages only
for row in fdot_table["rows"]:
for p in fdot_table["page_labels"]:
if p.startswith("L-"):
row["per_page"][p] = row["per_page"].get(p, 0)
for y in all_yolo_results:
page_label = f"L-{y['page_number']}"
for pi, lf in y["pay_items"].items():
# EXISTING ROW → OVERRIDE
if pi in row_map:
row_map[pi]["per_page"][page_label] = lf
# YOLO-ONLY ROW → ADD
else:
desc, unit = match_payitem_description(pi)
new_row = {
"pay_item": pi,
"description": desc or "",
"unit": unit or "LF",
"per_page": {
lbl: (lf if lbl == page_label else 0)
for lbl in fdot_table["page_labels"]
},
"total_plan": 0,
}
fdot_table["rows"].append(new_row)
row_map[pi] = new_row
# -----------------------------
# FINAL TOTALS (SINGLE SOURCE)
# -----------------------------
for row in fdot_table["rows"]:
row["total_plan"] = sum(
v for v in row["per_page"].values()
if isinstance(v, (int, float))
)
# -----------------------------
# EXCEL EXPORT (UNCHANGED)
# -----------------------------
excel_name = f"fdot_{request.user.id}_{int(os.times()[4])}.xlsx"
excel_path = os.path.join(
settings.MEDIA_ROOT, "history_excels", excel_name
)
os.makedirs(os.path.dirname(excel_path), exist_ok=True)
wb = Workbook()
ws = wb.active
ws.title = "Payitem Summary"
thin = Side(border_style="thin")
border = Border(left=thin, right=thin, top=thin, bottom=thin)
header_1 = ["PAY ITEM NO.", "DESCRIPTION", "UNIT"]
for lbl in fdot_table["page_labels"]:
header_1.extend([lbl, None])
header_1.extend(["TOTAL THIS SHEET", None, "GRAND TOTAL", None])
ws.append(header_1)
header_2 = ["", "", ""]
for _ in fdot_table["page_labels"]:
header_2.extend(["PLAN", "FINAL"])
header_2.extend(["PLAN", "FINAL", "PLAN", "FINAL"])
ws.append(header_2)
for r in fdot_table["rows"]:
row = [r["pay_item"], r["description"], r["unit"]]
for lbl in fdot_table["page_labels"]:
row.extend([r["per_page"].get(lbl, ""), ""])
row.extend([r["total_plan"], "", r["total_plan"], ""])
ws.append(row)
for row in ws.iter_rows():
for cell in row:
cell.border = border
cell.alignment = Alignment(
horizontal="center", vertical="center"
)
for i in range(1, ws.max_column + 1):
ws.column_dimensions[get_column_letter(i)].width = 18
wb.save(excel_path)
# -----------------------------
# SAVE HISTORY
# -----------------------------
history.pdf_file = pdf_form.cleaned_data["pdf"]
history.excel_file = os.path.join("history_excels", excel_name)
history.fdot_json = fdot_table
history.save()
except Exception as e:
error = str(e)
return render(request, "app/extract_sta.html", {
**context,
"pdf_form": pdf_form,
"fdot_table": fdot_table,
"history": history,
"error": error,
})
![]() |
Notes is a web-based application for online taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000+ notes created and continuing...
With notes.io;
- * You can take a note from anywhere and any device with internet connection.
- * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
- * You can quickly share your contents without website, blog and e-mail.
- * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
- * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.
Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.
Easy: Notes.io doesn’t require installation. Just write and share note!
Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )
Free: Notes.io works for 14 years and has been free since the day it was started.
You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;
Email: [email protected]
Twitter: http://twitter.com/notesio
Instagram: http://instagram.com/notes.io
Facebook: http://facebook.com/notesio
Regards;
Notes.io Team
