Skip to content

Add pyjhora_batch: headless batch horoscope reports (PDF/TXT/JHD) - #63

Closed
jivrajss wants to merge 2 commits into
naturalstupid:mainfrom
jivrajss:feat/headless-batch-generation
Closed

Add pyjhora_batch: headless batch horoscope reports (PDF/TXT/JHD)#63
jivrajss wants to merge 2 commits into
naturalstupid:mainfrom
jivrajss:feat/headless-batch-generation

Conversation

@jivrajss

Copy link
Copy Markdown

What this adds

A thin batch layer (pyjhora_batch/) on top of PyJHora that turns a CSV/Excel
list of birth details into a horoscope PDF and an importable Jagannatha Hora
.jhd per row. It reuses PyJHora's engine and PDF renderer — no calculations
are reimplemented.

  • python -m pyjhora_batch input.csv -o reports/ --workers auto
  • Single-record API: pyjhora_batch.generate_pdf(record, out_path)
  • CSV + Excel readers sharing one validation path (column aliases)
  • Resilient batch engine: per-record error isolation, deterministic filenames,
    batch.log, a failures.csv for retry, and optional multiprocessing
    (spawn pool, one QApplication per worker)
  • Writes .jhd files (PyJHora has no native .jhd export)
  • 72 pytest cases (fast; the PDF render is excluded), README, example datasets

Bug fixes (required for headless use), commit bd58591

  1. compute_horoscope() referenced config.initialize_runtime(...) but config
    was only imported under a __main__ guard → NameError that silently left
    self._horo unset. Imported config at module scope.
  2. During construction, combo-box signals reach _fill_panchangam_info /
    _update_tab_chart_information before self._horo exists; under PyQt6 an
    unhandled slot exception aborts the process. Added self._horo is None guards.

Note

ChartTabbed's date_of_birth/time_of_birth/place_of_birth constructor kwargs
are currently not applied (it falls back to now + IP location). The batch wrapper
works around this by injecting values via the public setters with networking off.
Happy to also submit a constructor fix separately if of interest.

jivrajss and others added 2 commits July 28, 2026 01:02
Two bugs prevented driving ChartTabbed without the interactive GUI:

1. compute_horoscope() calls config.initialize_runtime(), but `config`
   was only imported deep in the module under a __main__ guard, so at
   runtime it raised `NameError: name 'config' is not defined`. The
   exception was caught and logged, leaving self._horo unset and
   producing an empty PDF. Import `config` at module scope.

2. During construction, combo-box currentIndexChanged signals fire
   _kundali_chart_selection_changed -> _update_tab_chart_information ->
   _fill_panchangam_info, which dereference self._horo before the
   horoscope is computed (self._horo is None). Under PyQt6 an unhandled
   exception in a slot aborts the process. Guard both methods to return
   early when self._horo is None.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A batch layer over PyJHora's engine: a CSV/Excel of birth details in,
per-person reports out. Reimplements no calculations.

The report is extracted once as structured data (report_data.build_report)
and then rendered, so no output path needs Qt on screen:

* text_writer  -> wrapped plain-text report
* pdf_writer   -> vector PDF via reportlab, ~150 KB and searchable, versus
                  ~10 MB of 130-DPI JPEG for the Qt widget capture. That
                  capture is still available as --pdf-mode screenshot, since
                  it alone includes the drawn chart diagrams.
* jhd_writer   -> Jagannatha Hora .jhd, importable into the app. Every field
                  packs D.MMSS, longitude is East-negative, lines are CRLF;
                  the layout was derived byte-for-byte from a real export.

The Yoga and Raja Yoga tables report the yoga and the condition that matched,
and nothing else. The language resources carry a third "prediction" field, but
it is fixed boilerplate keyed on the yoga name -- identical for every chart the
yoga fires in -- and several yogas match very loosely, e.g.
_matrunasa_yoga_198_calculation is true whenever the Moon is hemmed by,
associated with, or aspected by any natural malefic, which covers most charts.
Printed next to a person's name and birth time, "The person's mother will have
a very early death" reads as an individual prognosis rather than as the
classical rule text it is.

CLI: --no-pdf / --no-jhd / --no-txt, --pdf-mode {vector,screenshot},
repeatable --dhasa (default vimsottari, 'all' for every system), -w N workers.

reportlab is required for the vector PDF; openpyxl (Excel input), pytest and
pypdf (tests) stay optional. Fixtures use a synthetic reference chart, and
the panchanga and D1 expectations are captured from ChartTabbed so they
cross-check the headless path rather than restating its own output.

169 passed, 1 skipped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jivrajss
jivrajss force-pushed the feat/headless-batch-generation branch from 78c97b7 to a495f61 Compare July 29, 2026 08:19
@jivrajss jivrajss changed the title Headless batch PDF + JHD generation (pyjhora_batch), plus headless ChartTabbed fixes Add pyjhora_batch: headless batch horoscope reports (PDF/TXT/JHD) Jul 29, 2026
@jivrajss jivrajss closed this Jul 29, 2026
@jivrajss

Copy link
Copy Markdown
Author

Superseded by #64 — same changes, clean branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant