gea-program 0.65.0__tar.gz → 0.66.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gea_program-0.65.0/gea_program.egg-info → gea_program-0.66.0}/PKG-INFO +5 -4
- {gea_program-0.65.0 → gea_program-0.66.0}/README.md +4 -3
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/__init__.py +1 -1
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/__main__.py +1 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/acceptance_tests.py +131 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/IT_SECURITY.md +5 -3
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/install.md +3 -3
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/site.md +1 -1
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/launcher.py +36 -1
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/service.py +18 -2
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/web/app.html +4 -4
- {gea_program-0.65.0 → gea_program-0.66.0/gea_program.egg-info}/PKG-INFO +5 -4
- {gea_program-0.65.0 → gea_program-0.66.0}/pyproject.toml +1 -1
- {gea_program-0.65.0 → gea_program-0.66.0}/LICENSE +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/alerts.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/backup.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/bench.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/blind_harness.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/casing_design.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog_map.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog_register.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/certificates.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/cli.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/client_reports.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/collision.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/config_versioning.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/conformance.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/control_room.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/correlation.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/dashboard.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/declarations.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/decline.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/deviation.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/dlis.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/dnp3.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/doctor.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/dossier.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/dossier_verify.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/drill_string.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/earth_model.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/economics.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/ed25519.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/edr.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/elevation.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/etp.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/example_register_map.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/fat_sat.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/files.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/fixtures/README.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/fixtures/comcat_mahoning_1990-2026.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/fixtures/ne_110m_coastline.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/follower.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/forward_model.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/frac_hits.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/friction_priors.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/gamma.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/geodesy.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/geomag.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/hartip.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/alarms.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/alerts.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/backup.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/casing.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/catalog.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/charts.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/collision.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/company-sign-in.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/conformance.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/control-room.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/data-in.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/declare.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/decline.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/dlis.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/doctor.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/dossier.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/drift.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/drillstring.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/economics.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/edr.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/etp.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/field-ports.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/files.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/frac-hits.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/historian.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/https.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/hydraulics.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/instruments.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/interval.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/invoice-check.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/map.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/month-end.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/notifications.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/opseis.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/osdu.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/pad-summary.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/patches.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/penetrator.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/plan.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/pore-pressure.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/quality.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/report-history.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/rig-time.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/seismic.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/setup.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/simulation.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/sites.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/slip.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/soak.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/sra.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/start.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/structure.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/tools.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/torque-drag.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/transients.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/vibration.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/well-report.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/help/well3d.md +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/helplib.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/housekeeping.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/hydraulics.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/icon.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/interval.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/invoice_check.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/jobs.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/live_ports.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/loadtest.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/modbus.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/modbus_rtu.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/model_card.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/month_end.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/notify.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/oidc.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/oidc_mock.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/op_seismicity.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/opcua_port.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/operator_app.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/osdu.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/pad_summary.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/patches.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/pdf_report.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/penetrator.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/permits.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/piwebapi.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/pore_pressure.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/ports.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/ppdm.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/project.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/quakeml.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reconciler.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/WMM2025.COF +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/eia_prices.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/iscwsa_rev4_example.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/iscwsa_rev5_example.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/l0701_sonic_gr.las.gz +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/l0701_sonic_gr.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/mahoning_example.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/mud_motor_specs.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/owsg_tool_models.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/penetrator_ratings.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/seismicity_protocols.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/tool_sources.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/us_outline.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/us_outline.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/volve_3d.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/volve_surfaces.json.gz +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/reference/volve_well_picks.csv.gz +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/report_history.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/rig_state.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/sample_record.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/sbom.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seedlink.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/segy.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seismic.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seismic_array.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seismic_film.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seismic_response.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seismic_track.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/seismic_watch.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/series_cache.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/service_life.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/setup_checklist.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/shapefile.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/shell.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/shut_in.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/simulation.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/site_map.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/sla_report.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/slip.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/soak.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/sra.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/store_forward.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/strata_join.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/structure.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/supervisor.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/survey_view.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/telemetry.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/timestamp.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/tls.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/tool_catalog.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/tool_library.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/tool_taxonomy.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/torque_drag.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/transient.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/tray.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/vibration.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/well3d.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/well_assembler.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/well_report.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/wellplan.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/wellpos.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/wits0.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/witsml.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/workspace.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea/xlsx_read.py +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea_program.egg-info/SOURCES.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/setup.cfg +0 -0
- {gea_program-0.65.0 → gea_program-0.66.0}/tests/test_acceptance.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gea-program
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.66.0
|
|
4
4
|
Summary: GEA-Program: downhole gauge monitoring - canonical measurement records, quality rules, drift evaluation with a re-fit change log, well-test validation, alarm management, model cards, store-and-forward, monthly SLA measurement, FAT/SAT protocols and a dashboard, generated from live objects in the client's reporting outline.
|
|
5
5
|
Author: Daniel T. Murphy
|
|
6
6
|
License: MPL-2.0
|
|
@@ -1426,11 +1426,12 @@ attaches the zips to the GitHub release of that tag.
|
|
|
1426
1426
|
|
|
1427
1427
|
### The Windows installer
|
|
1428
1428
|
|
|
1429
|
-
Every release also carries `GEA-Program-Setup-0.
|
|
1429
|
+
Every release also carries `GEA-Program-Setup-0.66.0.exe` (for 0.66.0): the
|
|
1430
1430
|
same Windows kit installed like any Windows program, for the signed-in user
|
|
1431
1431
|
alone and with no administrator rights (`%LOCALAPPDATA%\Programs\GEA-Program`).
|
|
1432
1432
|
It asks for the site workspace (an existing one such as `C:\site` is used as
|
|
1433
|
-
it is
|
|
1433
|
+
it is, its name included; a new one is made with the site name it asks for,
|
|
1434
|
+
which heads every report), runs the kit's `install.cmd` with no network, and adds Start-menu and
|
|
1434
1435
|
desktop shortcuts, an Add/Remove Programs entry and, when chosen, a start at
|
|
1435
1436
|
sign-in. The shortcut **GEA-Program** starts the control panel when it is not
|
|
1436
1437
|
running and opens it in Microsoft Edge's app window (its own window and
|
|
@@ -1442,7 +1443,7 @@ it, removes the program and leaves the workspace. Silent, for a site's
|
|
|
1442
1443
|
software deployment:
|
|
1443
1444
|
|
|
1444
1445
|
```
|
|
1445
|
-
GEA-Program-Setup-0.
|
|
1446
|
+
GEA-Program-Setup-0.66.0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /WORKSPACE="C:\site" /SITENAME="Pad 3" /TASKS="desktopicon"
|
|
1446
1447
|
```
|
|
1447
1448
|
|
|
1448
1449
|
The setup is built by Inno Setup 6 from `tools/installer.iss` in the same
|
|
@@ -1387,11 +1387,12 @@ attaches the zips to the GitHub release of that tag.
|
|
|
1387
1387
|
|
|
1388
1388
|
### The Windows installer
|
|
1389
1389
|
|
|
1390
|
-
Every release also carries `GEA-Program-Setup-0.
|
|
1390
|
+
Every release also carries `GEA-Program-Setup-0.66.0.exe` (for 0.66.0): the
|
|
1391
1391
|
same Windows kit installed like any Windows program, for the signed-in user
|
|
1392
1392
|
alone and with no administrator rights (`%LOCALAPPDATA%\Programs\GEA-Program`).
|
|
1393
1393
|
It asks for the site workspace (an existing one such as `C:\site` is used as
|
|
1394
|
-
it is
|
|
1394
|
+
it is, its name included; a new one is made with the site name it asks for,
|
|
1395
|
+
which heads every report), runs the kit's `install.cmd` with no network, and adds Start-menu and
|
|
1395
1396
|
desktop shortcuts, an Add/Remove Programs entry and, when chosen, a start at
|
|
1396
1397
|
sign-in. The shortcut **GEA-Program** starts the control panel when it is not
|
|
1397
1398
|
running and opens it in Microsoft Edge's app window (its own window and
|
|
@@ -1403,7 +1404,7 @@ it, removes the program and leaves the workspace. Silent, for a site's
|
|
|
1403
1404
|
software deployment:
|
|
1404
1405
|
|
|
1405
1406
|
```
|
|
1406
|
-
GEA-Program-Setup-0.
|
|
1407
|
+
GEA-Program-Setup-0.66.0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /WORKSPACE="C:\site" /SITENAME="Pad 3" /TASKS="desktopicon"
|
|
1407
1408
|
```
|
|
1408
1409
|
|
|
1409
1410
|
The setup is built by Inno Setup 6 from `tools/installer.iss` in the same
|
|
@@ -823,6 +823,7 @@ def main(argv=None) -> int:
|
|
|
823
823
|
p_la.add_argument("--selftest", action="store_true", help="say what a launch would do here (the kit, the workspace, the window, the command), start nothing")
|
|
824
824
|
p_la.add_argument("--json", action="store_true")
|
|
825
825
|
p_la.add_argument("--set-workspace", type=str, default=None, help="record the site workspace for this installation (the installer runs it; never a folder inside the program's own)")
|
|
826
|
+
p_la.add_argument("--site-name", type=str, default=None, help="with --set-workspace: make the workspace with this name when there is none there yet (an existing one is left as it is; empty names it after its folder)")
|
|
826
827
|
p_ty = sub.add_parser("tray", help="the program's icon in the Windows notification area: running or stopped, and a menu to open, start or stop the control panel")
|
|
827
828
|
p_ty.add_argument("--workspace", type=str, default=None, help="the workspace folder (as gea launch finds it)")
|
|
828
829
|
p_ty.add_argument("--port", type=int, default=8765)
|
|
@@ -14549,6 +14549,136 @@ def section_dh_windows_installer(tmp: str) -> None:
|
|
|
14549
14549
|
+ (f" [failed: {', '.join(failed6)}]" if failed6 else ""))
|
|
14550
14550
|
|
|
14551
14551
|
|
|
14552
|
+
def section_di_site_name(tmp: str) -> None:
|
|
14553
|
+
"""Section DI - the site's name: asked for by the installer and given to a workspace it makes, an existing workspace
|
|
14554
|
+
left with its own; never written into the kit's scripts; changed on the Administration page and in the first-run
|
|
14555
|
+
guide, heading every report from then on, audited; the workflow's own install checks it."""
|
|
14556
|
+
import argparse as _ap
|
|
14557
|
+
import contextlib as _cl
|
|
14558
|
+
import http.cookiejar
|
|
14559
|
+
import importlib.util
|
|
14560
|
+
import io as _io
|
|
14561
|
+
import urllib.error
|
|
14562
|
+
import urllib.request
|
|
14563
|
+
from . import launcher as L
|
|
14564
|
+
from .doctor import kit_dir as _doctor_kit
|
|
14565
|
+
from .service import Service, Users
|
|
14566
|
+
from .workspace import Workspace
|
|
14567
|
+
pkg = Path(__file__).parent
|
|
14568
|
+
d = Path(tmp, "site_name"); d.mkdir()
|
|
14569
|
+
checkout = (pkg.parent / "pyproject.toml").exists() and (pkg.parent / "tools" / "installer.iss").exists()
|
|
14570
|
+
|
|
14571
|
+
# -- DI1 the installer's workspace, made with its name ---------------------------------------------------------------------------
|
|
14572
|
+
kit = d / "Programs" / "GEA-Program"; (kit / "python").mkdir(parents=True)
|
|
14573
|
+
(kit / "start-dashboard.cmd").write_text("@echo off\n", encoding="utf-8")
|
|
14574
|
+
new_ws, old_ws, plain_ws = str(d / "new site"), str(d / "old site"), str(d / "Pad 7")
|
|
14575
|
+
Workspace.create(old_ws, "Pad 3", actor="tester")
|
|
14576
|
+
old_bytes = Path(old_ws, "workspace.json").read_bytes()
|
|
14577
|
+
saved = L.kit_dir
|
|
14578
|
+
outs = {}
|
|
14579
|
+
try:
|
|
14580
|
+
L.kit_dir = lambda executable=None: kit
|
|
14581
|
+
for key, ws_, nm in (("new", new_ws, "Jörg's Pad 3 – east"), ("old", old_ws, "Something else"), ("plain", plain_ws, ""), ("quote", str(d / "q site"), 'Pad "3"'),
|
|
14582
|
+
("record_only", str(d / "rec site"), None)):
|
|
14583
|
+
buf = _io.StringIO()
|
|
14584
|
+
with _cl.redirect_stdout(buf):
|
|
14585
|
+
rc = L.main(_ap.Namespace(set_workspace=ws_, site_name=nm, selftest=False, workspace=None, port=8765, background=False, no_tray=False))
|
|
14586
|
+
outs[key] = (rc, buf.getvalue())
|
|
14587
|
+
finally:
|
|
14588
|
+
L.kit_dir = saved
|
|
14589
|
+
name_of = lambda p: json.loads(Path(p, "workspace.json").read_text(encoding="utf-8"))["name"] if Path(p, "workspace.json").exists() else None
|
|
14590
|
+
c1 = {
|
|
14591
|
+
"made_named": outs["new"][0] == 0 and name_of(new_ws) == "Jörg's Pad 3 – east" and "made, named Jörg's Pad 3 – east" in outs["new"][1]
|
|
14592
|
+
and Workspace(new_ws).audit_log()[-1]["actor"] == "installer",
|
|
14593
|
+
"existing_kept": outs["old"][0] == 0 and Path(old_ws, "workspace.json").read_bytes() == old_bytes and "exists and is used as it is" in outs["old"][1],
|
|
14594
|
+
"empty_is_folder": outs["plain"][0] == 0 and name_of(plain_ws) == "Pad 7",
|
|
14595
|
+
"quote_not_taken": outs["quote"][0] == 2 and name_of(str(d / "q site")) is None and "quotation marks" in outs["quote"][1],
|
|
14596
|
+
"record_only": outs["record_only"][0] == 0 and name_of(str(d / "rec site")) is None,
|
|
14597
|
+
"limits": L.check_site_name("x" * 81) is not None and L.check_site_name("x" * 80) is None and L.check_site_name("a\tb") is not None,
|
|
14598
|
+
}
|
|
14599
|
+
failed1 = [k for k, v in c1.items() if not v]
|
|
14600
|
+
ok(not failed1,
|
|
14601
|
+
"DI1 the installer's site name: a workspace the setup makes is made with the name asked for (any letters; no quotation marks, tabs or "
|
|
14602
|
+
"line breaks; 80 characters at most), or the folder's name when none is given; an existing workspace is used exactly as it is, its "
|
|
14603
|
+
"own name kept, byte for byte" + (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
14604
|
+
|
|
14605
|
+
# -- DI2 no site's name in the kit; the setup asks only when it makes the workspace ------------------------------------------------
|
|
14606
|
+
if checkout:
|
|
14607
|
+
spec = importlib.util.spec_from_file_location("di_installer", str(pkg.parent / "tools" / "build_installer.py"))
|
|
14608
|
+
bi = importlib.util.module_from_spec(spec); spec.loader.exec_module(bi)
|
|
14609
|
+
start_cmd, start_sh = bi.WIN_SCRIPTS["start-dashboard.cmd"], bi.LINUX_SCRIPTS["start-dashboard.sh"]
|
|
14610
|
+
iss = (pkg.parent / "tools" / "installer.iss").read_text(encoding="utf-8")
|
|
14611
|
+
wf = (pkg.parent / ".github" / "workflows" / "build-installer.yml").read_text(encoding="utf-8")
|
|
14612
|
+
code = iss[iss.index("[Code]"):]
|
|
14613
|
+
nb = code.split("function NextButtonClick", 1)[1].split("\nend;", 1)[0]
|
|
14614
|
+
c2 = {
|
|
14615
|
+
"page": "CreateInputQueryPage(WsPage.ID" in code and "{param:SITENAME|}" in code and "Result := WorkspaceExists();" in code.split("function ShouldSkipPage", 1)[1]
|
|
14616
|
+
and "SiteNameProblem(SiteName())" in nb and code.count("SiteNameProblem(SiteName())") == 2,
|
|
14617
|
+
"made_by_program": "--site-name \"' + SiteName() + '\"'" in code and "Pos('\"', S) > 0" in code,
|
|
14618
|
+
"workflow": '/SITENAME="CI Pad"' in wf and "expected 'CI Pad'" in wf and "the upgrade changed the existing workspace" in wf,
|
|
14619
|
+
}
|
|
14620
|
+
where2 = "the checkout's templates and installer"
|
|
14621
|
+
else:
|
|
14622
|
+
kd = _doctor_kit(); where2 = f"the installed kit at {kd}"
|
|
14623
|
+
start_cmd = open(os.path.join(kd, "start-dashboard.cmd"), encoding="utf-8").read() if kd and os.path.isfile(os.path.join(kd, "start-dashboard.cmd")) else ""
|
|
14624
|
+
start_sh = open(os.path.join(kd, "start-dashboard.sh"), encoding="utf-8").read() if kd and os.path.isfile(os.path.join(kd, "start-dashboard.sh")) else ""
|
|
14625
|
+
c2 = {}
|
|
14626
|
+
init_lines = [ln for ln in (start_cmd + "\n" + start_sh).splitlines() if "--action init" in ln]
|
|
14627
|
+
c2["kit_unnamed"] = all("--name" not in ln for ln in init_lines) and "Pad 3" not in start_cmd + start_sh and (bool(init_lines) or not (start_cmd or start_sh))
|
|
14628
|
+
failed2 = [k for k, v in c2.items() if not v]
|
|
14629
|
+
ok(not failed2,
|
|
14630
|
+
f"DI2 ({where2}) the kit's launchers make a missing workspace named after its folder - no site's name is written into them (before "
|
|
14631
|
+
"v0.66 every kit named a new workspace Pad 3); the setup asks for the name only when it makes the workspace, skips the question for "
|
|
14632
|
+
"one that exists, passes it to the program to make it, and its build makes one named and upgrades it unchanged"
|
|
14633
|
+
+ (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
|
|
14634
|
+
|
|
14635
|
+
# -- DI3 renamed in the control panel ----------------------------------------------------------------------------------------------
|
|
14636
|
+
wsp = str(d / "panel"); Workspace.create(wsp, "site", actor="tester")
|
|
14637
|
+
users = Users(str(Path(wsp, "users.json")))
|
|
14638
|
+
users.add("adm", "admin-pass-123", "admin"); users.add("op", "op-pass-123", "operator")
|
|
14639
|
+
svc = Service(wsp, port=0, scheduler=False).start()
|
|
14640
|
+
base_url = svc.url.rstrip("/")
|
|
14641
|
+
|
|
14642
|
+
def opener(name, pw_):
|
|
14643
|
+
o = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
|
|
14644
|
+
rq = urllib.request.Request(base_url + "/api/login", method="POST", data=json.dumps({"name": name, "password": pw_}).encode())
|
|
14645
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1"); o.open(rq, timeout=30)
|
|
14646
|
+
return o
|
|
14647
|
+
|
|
14648
|
+
def call(o, method, path, body=None):
|
|
14649
|
+
rq = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
|
|
14650
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1")
|
|
14651
|
+
try:
|
|
14652
|
+
with o.open(rq, timeout=60) as rr_:
|
|
14653
|
+
return rr_.status, json.loads(rr_.read())
|
|
14654
|
+
except urllib.error.HTTPError as e:
|
|
14655
|
+
return e.code, json.loads(e.read())
|
|
14656
|
+
try:
|
|
14657
|
+
adm, op = opener("adm", "admin-pass-123"), opener("op", "op-pass-123")
|
|
14658
|
+
s_op, _ = call(op, "POST", "/api/site", {"site": {"name": "Pad 9"}})
|
|
14659
|
+
s_empty, e_empty = call(adm, "POST", "/api/site", {"site": {"name": " "}})
|
|
14660
|
+
s_q, e_q = call(adm, "POST", "/api/site", {"site": {"name": 'Pad "9"'}})
|
|
14661
|
+
s_ok, r_ok = call(adm, "POST", "/api/site", {"site": {"name": "Pad 9 – north", "units": "si"}})
|
|
14662
|
+
s_only, r_only = call(adm, "POST", "/api/site", {"site": {"name": "Pad 9 – north"}})
|
|
14663
|
+
_, sess = call(op, "GET", "/api/session")
|
|
14664
|
+
finally:
|
|
14665
|
+
svc.stop()
|
|
14666
|
+
renames = [e for e in Workspace(wsp).audit_log() if e.get("action") == "workspace.rename"]
|
|
14667
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
14668
|
+
c3 = {
|
|
14669
|
+
"admin_only": s_op == 403,
|
|
14670
|
+
"checked": s_empty == 400 and "not empty" in e_empty.get("error", "") and s_q == 400 and "quotation" in e_q.get("error", ""),
|
|
14671
|
+
"renamed": s_ok == 200 and r_ok.get("site", {}).get("units") == "si" and sess.get("workspace") == "Pad 9 – north" and Workspace(wsp).manifest["name"] == "Pad 9 – north",
|
|
14672
|
+
"audited_once": len(renames) == 1 and renames[0]["actor"] == "adm" and renames[0]["detail"] == {"from": "site", "to": "Pad 9 – north"} and s_only == 200,
|
|
14673
|
+
"page": all(x in page_src for x in ('id="stSiteName"', 'id="wSiteName"', "{name: nm}", "The site's name heads every report")),
|
|
14674
|
+
}
|
|
14675
|
+
failed3 = [k for k, v in c3.items() if not v]
|
|
14676
|
+
ok(not failed3,
|
|
14677
|
+
"DI3 the site's name changed in the control panel (Administration's site settings, and the first-run guide's first step), by an "
|
|
14678
|
+
"administrator only: an empty name or one with quotation marks answered, the new name heading the page and every report from then on, "
|
|
14679
|
+
"one audit line per change" + (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
14680
|
+
|
|
14681
|
+
|
|
14552
14682
|
def main() -> int:
|
|
14553
14683
|
print("GEA-Program - ACCEPTANCE SUITE (the product gate)")
|
|
14554
14684
|
# a handle a job subprocess still holds at the end must not turn a finished gate into a traceback on Windows:
|
|
@@ -14664,6 +14794,7 @@ def main() -> int:
|
|
|
14664
14794
|
section_df_trusted_timestamp(tmp)
|
|
14665
14795
|
section_dg_casing_program(tmp)
|
|
14666
14796
|
section_dh_windows_installer(tmp)
|
|
14797
|
+
section_di_site_name(tmp)
|
|
14667
14798
|
if _FAILS:
|
|
14668
14799
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
14669
14800
|
for f in _FAILS:
|
|
@@ -24,9 +24,11 @@ system service (a per-user scheduled task only if the site runs
|
|
|
24
24
|
and desktop, an optional shortcut in the user's Startup folder, and the
|
|
25
25
|
user's own Add/Remove Programs entry (`HKCU`, the only registry key it
|
|
26
26
|
writes, removed by its uninstaller). Silent install for a software
|
|
27
|
-
deployment: `/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /WORKSPACE="C:\site"
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
deployment: `/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /WORKSPACE="C:\site"`
|
|
28
|
+
(`/SITENAME="Pad 3"` names a workspace the setup makes).
|
|
29
|
+
The setup never writes into an existing site workspace (a new one it makes,
|
|
30
|
+
with the site name asked for) and will not take one inside the program's own
|
|
31
|
+
folder; the uninstaller stops the control panel, removes the
|
|
30
32
|
program and leaves the workspace. The program's window is Microsoft Edge's
|
|
31
33
|
app window (`msedge --app=` on the local address); its notification-area
|
|
32
34
|
icon (standard library `ctypes`, `Shell_NotifyIconW`) reads only whether the
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> GEA-Program-Setup: the program installed for you like any Windows program - a window of its own, an icon in the notification area, Start-menu and desktop shortcuts, an Add/Remove Programs entry, upgrades in place - with no administrator rights and the site's data left where it is.
|
|
4
4
|
|
|
5
|
-
**The command**: download the setup from the release on GitHub (`GEA-Program-Setup-0.
|
|
5
|
+
**The command**: download the setup from the release on GitHub (`GEA-Program-Setup-0.66.0.exe` for this version) and run it. It installs for you alone, under `%LOCALAPPDATA%\Programs\GEA-Program`, and asks for the site workspace - the folder that holds the wells, reports, records, accounts and keys. An existing one such as `C:\site` is used exactly as it is, its name included; for a new one (by default `%LOCALAPPDATA%\GEA-Program\site`) it also asks the site's name, which heads every report, and makes the workspace with it (left empty, the workspace is named after its folder; an administrator renames the site in Administration's site settings). Then the Start menu's **GEA-Program** (and the desktop shortcut) starts the control panel when it is not running and opens it in a window of its own. A newer setup installs over the older one: it stops the control panel, replaces the program, keeps the workspace and the choices made before. For a site's software deployment: `GEA-Program-Setup-0.66.0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /WORKSPACE="C:\site" /SITENAME="Pad 3" /TASKS="desktopicon"` (`/SITENAME` names a workspace the setup makes; one that exists keeps its own name). From a terminal: `gea launch` does what the shortcut does, `gea launch --selftest` says what it would do, `gea tray --selftest` checks the icon.
|
|
6
6
|
|
|
7
7
|
**The window**: Microsoft Edge's app window (`msedge --app=`: the control panel with no tabs and no address bar, its own button on the taskbar, signed in as the browser is), else Google Chrome's, else a tab in the default browser. The control panel itself runs in the window titled "GEA - Operations Control Panel", minimised on the taskbar: the window that starts it again when the panel asks for a restart and says why it stopped when it stops. Closing that window stops the panel.
|
|
8
8
|
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
|
|
11
11
|
**Starting at sign-in**: the setup's "Start the control panel when I sign in to Windows" puts a GEA-Program shortcut in the Startup folder: the control panel starts in the background with its icon, and no window opens until you open one. The install kit's `register-service.cmd` (a scheduled task) does the same for a kit that was not installed by the setup.
|
|
12
12
|
|
|
13
|
-
**What it writes**: the program under `%LOCALAPPDATA%\Programs\GEA-Program` (the install kit, and the package installed into the kit's own Python by its `install.cmd`, from its own wheels, with no network); `site-workspace.txt` there, the workspace you chose; the shortcuts; the Add/Remove Programs entry under the current user. Setup and uninstall never write into the
|
|
13
|
+
**What it writes**: the program under `%LOCALAPPDATA%\Programs\GEA-Program` (the install kit, and the package installed into the kit's own Python by its `install.cmd`, from its own wheels, with no network); `site-workspace.txt` there, the workspace you chose; the shortcuts; the Add/Remove Programs entry under the current user. Setup and uninstall never write into an existing workspace (a new one the setup makes, with its name, and leaves at that), never move it and never delete it, and will not take a workspace inside the program's own folder (which an upgrade replaces and the uninstaller removes). Uninstalling stops the control panel and its icon, then removes the program and what `install.cmd` added to it.
|
|
14
14
|
|
|
15
15
|
**The number to check**: Add/Remove Programs lists GEA-Program with the version you installed; `gea doctor --workspace C:\site` ends with `nothing blocks serving`; the Start menu's **Verify GEA-Program** runs the acceptance gate from the installation and ends with `[ACCEPTANCE] OK - N checks passed`. The release's build installs, upgrades and uninstalls the setup silently before it is published, with the control panel running, and checks the workspace untouched afterwards.
|
|
16
16
|
|
|
17
|
-
**Signed**: when the publisher's code-signing certificate is configured for the build, the setup is signed with it (Authenticode, timestamped) and Windows names the publisher; until then it ships unsigned and Windows SmartScreen says "unknown publisher" (More info, then Run anyway). The build's provenance holds either way: `gh attestation verify GEA-Program-Setup-0.
|
|
17
|
+
**Signed**: when the publisher's code-signing certificate is configured for the build, the setup is signed with it (Authenticode, timestamped) and Windows names the publisher; until then it ships unsigned and Windows SmartScreen says "unknown publisher" (More info, then Run anyway). The build's provenance holds either way: `gh attestation verify GEA-Program-Setup-0.66.0.exe -R Daniel8Murphy0007/GEA-Program`. The uninstaller the setup leaves behind is Inno Setup's own and is not signed separately.
|
|
18
18
|
|
|
19
19
|
**What this page will not call a measurement**: the icon's running or stopped is whether the control panel's port answers on this computer, read every three seconds - not whether every patch, job or report behind it is healthy (Home and the Verification page say that).
|
|
20
20
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> The workspace folder, the four roles and what each cannot do, the audit log.
|
|
4
4
|
|
|
5
|
-
**The command**: `gea workspace --path C:\site --action init --name "Pad 3"`; `gea serve --workspace C:\site` (loopback by default; it opens the control panel in your browser once it is listening, `--no-browser` for a scheduled start, and the window it runs in prints what happens on the page - sign-ins, jobs, stops - as it happens; `--behind-proxy` with a TLS proxy in front, see `deploy/README.md`); `gea users --workspace C:\site --action add --name ... --role admin` (the password from `GEA_PASSWORD`, never the command line). `gea workspace --path C:\site --action rename --name "Pad 3"` sets the site's name as every report prints it.
|
|
5
|
+
**The command**: `gea workspace --path C:\site --action init --name "Pad 3"`; `gea serve --workspace C:\site` (loopback by default; it opens the control panel in your browser once it is listening, `--no-browser` for a scheduled start, and the window it runs in prints what happens on the page - sign-ins, jobs, stops - as it happens; `--behind-proxy` with a TLS proxy in front, see `deploy/README.md`); `gea users --workspace C:\site --action add --name ... --role admin` (the password from `GEA_PASSWORD`, never the command line). `gea workspace --path C:\site --action rename --name "Pad 3"` sets the site's name as every report prints it - as does Site name in Administration's site settings (and the first-run guide's first step), for an administrator; reports already written keep the name they were written with.
|
|
6
6
|
|
|
7
7
|
**What it writes**: `workspace.json`, `wells/<id>/{source,records}`, `config/` (every configuration versioned, diffed, reversible), `monitor/`, `reports/`, `jobs/<id>/{job.json,log.txt}`, `records/audit.jsonl` (append-only, every action with the actor and the SHA-256 of its inputs), `users.json` (salted PBKDF2-SHA256, never a password).
|
|
8
8
|
|
|
@@ -134,6 +134,33 @@ def set_workspace(kit: Optional[Path], path: str) -> str:
|
|
|
134
134
|
return path
|
|
135
135
|
|
|
136
136
|
|
|
137
|
+
SITE_NAME_MAX = 80
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def check_site_name(name: Optional[str]) -> Optional[str]:
|
|
141
|
+
"""Why a site name cannot be used, or None. Empty is allowed: the workspace is then named after its folder."""
|
|
142
|
+
name = (name or '').strip()
|
|
143
|
+
if len(name) > SITE_NAME_MAX:
|
|
144
|
+
return f'a site name of {len(name)} characters; {SITE_NAME_MAX} at most (it heads every report)'
|
|
145
|
+
if any(c in name for c in '"\r\n\t'):
|
|
146
|
+
return 'a site name holds no quotation marks, line breaks or tabs'
|
|
147
|
+
return None
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def create_workspace(path: str, site_name: Optional[str], actor: str = 'installer') -> Optional[str]:
|
|
151
|
+
"""Make the workspace with its name when there is none at `path` yet; an existing workspace is left exactly as it
|
|
152
|
+
is (its name is changed on the Administration page). Returns the name it was made with, or None when it existed."""
|
|
153
|
+
if os.path.isfile(os.path.join(path, 'workspace.json')):
|
|
154
|
+
return None
|
|
155
|
+
why = check_site_name(site_name)
|
|
156
|
+
if why:
|
|
157
|
+
raise LaunchError(why)
|
|
158
|
+
from .workspace import Workspace
|
|
159
|
+
name = (site_name or '').strip() or os.path.basename(os.path.normpath(path))
|
|
160
|
+
Workspace.create(path, name, actor=actor)
|
|
161
|
+
return name
|
|
162
|
+
|
|
163
|
+
|
|
137
164
|
def port_open(port: int, host: str = '127.0.0.1', timeout: float = 0.4) -> bool:
|
|
138
165
|
try:
|
|
139
166
|
with socket.create_connection((host, int(port)), timeout=timeout):
|
|
@@ -407,7 +434,15 @@ def main(a) -> int:
|
|
|
407
434
|
except LaunchError as e:
|
|
408
435
|
say('GEA-Program', f'The site workspace was not recorded: {e}', error=True)
|
|
409
436
|
return 2
|
|
410
|
-
|
|
437
|
+
made = None
|
|
438
|
+
if getattr(a, 'site_name', None) is not None:
|
|
439
|
+
try:
|
|
440
|
+
made = create_workspace(path, a.site_name)
|
|
441
|
+
except (LaunchError, OSError) as e:
|
|
442
|
+
say('GEA-Program', f'The site workspace was recorded but not made: {e}', error=True)
|
|
443
|
+
return 2
|
|
444
|
+
say('GEA-Program', f'site workspace: {path} (recorded in {Path(kit_dir()) / WORKSPACE_FILE})'
|
|
445
|
+
+ (f'; made, named {made}' if made else ('; it exists and is used as it is' if getattr(a, 'site_name', None) is not None else '')))
|
|
411
446
|
return 0
|
|
412
447
|
if getattr(a, 'selftest', False):
|
|
413
448
|
p = plan(a.workspace, a.port)
|
|
@@ -1260,9 +1260,25 @@ class App:
|
|
|
1260
1260
|
return {'jobs': out}
|
|
1261
1261
|
|
|
1262
1262
|
def set_site(self, user: dict, site: dict) -> dict:
|
|
1263
|
-
"""Site-wide display defaults in the manifest: units, time zone, display name, contact line
|
|
1263
|
+
"""Site-wide display defaults in the manifest: units, time zone, display name, contact line - and `name`, the
|
|
1264
|
+
site's name that heads every report (the workspace's own name, audited as workspace.rename). Admin only."""
|
|
1265
|
+
site = dict(site or {})
|
|
1266
|
+
if 'name' in site:
|
|
1267
|
+
from .launcher import check_site_name
|
|
1268
|
+
nm = site.pop('name')
|
|
1269
|
+
if not isinstance(nm, str) or not nm.strip():
|
|
1270
|
+
raise ApiError(400, 'the site name must be text, and not empty: it heads every report')
|
|
1271
|
+
why = check_site_name(nm)
|
|
1272
|
+
if why:
|
|
1273
|
+
raise ApiError(400, why)
|
|
1274
|
+
try:
|
|
1275
|
+
self.ws.rename(nm.strip(), actor=user['name'])
|
|
1276
|
+
except WorkspaceError as e:
|
|
1277
|
+
raise ApiError(400, str(e))
|
|
1278
|
+
if not site:
|
|
1279
|
+
return dict(self.ws.manifest.get('site') or {})
|
|
1264
1280
|
cur = dict(self.ws.manifest.get('site') or {})
|
|
1265
|
-
for k, v in
|
|
1281
|
+
for k, v in site.items():
|
|
1266
1282
|
if k not in ('units', 'time_zone', 'display_name', 'contact', 'wizard_done'):
|
|
1267
1283
|
raise ApiError(400, f'unknown site setting: {k}')
|
|
1268
1284
|
if k == 'units' and v not in ('field', 'si'):
|
|
@@ -1804,7 +1804,7 @@ VIEWS.admin = async () => {
|
|
|
1804
1804
|
const nt = await get('/api/notifications');
|
|
1805
1805
|
let SS = {sessions: []}; try { SS = await get('/api/sessions'); } catch (e) {}
|
|
1806
1806
|
h += `<div class="card"><h3>Live sessions (${SS.sessions.length})</h3><p class="small muted">Who is signed in, from where, since when. Revoking signs that session out at its next request. ${esc(SS.note || '')}</p><table><thead><tr><th>User</th><th>Role</th><th>From</th><th>Signed in</th><th>Last seen</th><th>Expires</th><th></th></tr></thead><tbody>${SS.sessions.map(x => `<tr><td>${esc(x.name)}${x.via === 'company' ? ' <span class="small muted">(company)</span>' : ''}</td><td>${esc(x.role)}</td><td class="mono small">${esc(x.client)}</td><td class="small">${tz(x.created_utc)}</td><td class="small">${tz(x.last_seen_utc)}</td><td class="small">${tz(x.expires_utc)}</td><td><button class="secondary" data-rs="${esc(x.sid)}" type="button">Revoke</button> <button class="secondary danger" data-ru="${esc(x.name)}" type="button">All of ${esc(x.name)}</button></td></tr>`).join('') || '<tr><td colspan="7" class="muted">none</td></tr>'}</tbody></table></div>`;
|
|
1807
|
-
h += `<div class="card"><h3>Site settings</h3><p class="small muted">
|
|
1807
|
+
h += `<div class="card"><h3>Site settings</h3><p class="small muted">The site's name heads every report written from now on and the top of this page (reports already written keep theirs; a rename is in the audit log). Then defaults for everyone who has not chosen their own: display units and time zone, the name on the home page, a contact line for the sign-in screen.</p><div class="row"><label>Site name (on every report)<input id="stSiteName" maxlength="80" required value="${esc(workspaceName)}"></label><label>Display name<input id="stName" value="${esc(SITE.display_name || '')}" placeholder="${esc(workspaceName)}"></label><label>Units<select id="stUnits"><option value="field" ${(SITE.units || 'field') === 'field' ? 'selected' : ''}>field (psi, °F, ft)</option><option value="si" ${SITE.units === 'si' ? 'selected' : ''}>SI (kPa, °C, m)</option></select></label><label>Time zone<input id="stTz" value="${esc(SITE.time_zone || 'UTC')}" placeholder="UTC or America/Chicago" list="tzList"></label><label>Contact<input id="stContact" value="${esc(SITE.contact || '')}" placeholder="who to call"></label><button id="stSave" type="button">Save</button></div><datalist id="tzList">${['UTC', 'America/Chicago', 'America/Denver', 'America/New_York', 'America/Los_Angeles', 'America/Anchorage', 'Europe/London', 'Europe/Oslo', 'Asia/Dubai', 'Asia/Kuala_Lumpur', 'Australia/Perth'].map(z => `<option value="${z}">`).join('')}</datalist></div>`;
|
|
1808
1808
|
h += `<div class="card"><h3>Notifications</h3><p class="small muted">Rules route events (alarm activations by priority, failed jobs, patches down, items waiting for approval) to channels: a webhook URL or an SMTP mailbox. Secrets stay out of the configuration - an SMTP password is read from the environment variable the channel names. The configuration is versioned as <span class="mono">notifications</span>.</p>`;
|
|
1809
1809
|
h += nt.configured ? `<table><thead><tr><th>Channel</th><th>Kind</th><th>Target</th><th></th></tr></thead><tbody>${nt.channels.map(c => `<tr><td>${esc(c.name)}</td><td>${esc(c.kind)}</td><td class="mono small">${esc(c.target)}${c.secret ? ' <span class="muted">(with credentials)</span>' : ''}</td><td><button class="secondary" data-nt="${esc(c.name)}" type="button">Send a test</button></td></tr>`).join('')}</tbody></table><p class="small">${nt.rules.length} rule(s): ${nt.rules.map(r => `${esc(r.event)}${r.priority ? ' ' + esc(r.priority.join('/')) : ''} → ${esc((r.channels || []).join(', '))}`).join(' · ')} · quiet window ${nt.quiet_s} s</p>` : `<p class="small">Not configured. <button class="secondary" id="ntExample" type="button">Load the example</button> into the editor, change the URL or mailbox, validate and commit.</p>`;
|
|
1810
1810
|
h += `<details><summary>Edit the configuration</summary><label>JSON<textarea id="ntCfg" spellcheck="false"></textarea></label><div class="row"><label>Note<input id="ntNote"></label><button class="secondary" id="ntLoad" type="button">Load current</button><button id="ntSave" type="button">Validate and commit</button></div></details>`;
|
|
@@ -1831,7 +1831,7 @@ VIEWS.admin = async () => {
|
|
|
1831
1831
|
const o = await get('/api/overview'); const wsPath = o.workspace.path;
|
|
1832
1832
|
document.querySelectorAll('[data-rs]').forEach(b => b.onclick = async () => { try { const r = await post('/api/sessions/revoke', {sid: b.dataset.rs}); toast(`${r.revoked} session(s) revoked`, 'ok'); route(); } catch (e) { toast(e.message, 'err'); } });
|
|
1833
1833
|
document.querySelectorAll('[data-ru]').forEach(b => b.onclick = async () => { if (!confirm(`Sign ${b.dataset.ru} out of every session?`)) return; try { const r = await post('/api/sessions/revoke', {name: b.dataset.ru}); toast(`${r.revoked} session(s) revoked`, 'ok'); if (b.dataset.ru === me.name) { me = null; boot(); } else route(); } catch (e) { toast(e.message, 'err'); } });
|
|
1834
|
-
$('#stSave').onclick = async () => { try { const r = await post('/api/site', {site: {display_name: $('#stName').value, units: $('#stUnits').value, time_zone: $('#stTz').value, contact: $('#stContact').value}}); SITE = r.site; toast('Site settings saved', 'ok'); route(); } catch (e) { toast(e.message, 'err'); } };
|
|
1834
|
+
$('#stSave').onclick = async () => { const nm = $('#stSiteName').value.trim(); if (!nm) return toast('The site needs a name: it heads every report', 'err'); try { const r = await post('/api/site', {site: {...(nm !== workspaceName ? {name: nm} : {}), display_name: $('#stName').value, units: $('#stUnits').value, time_zone: $('#stTz').value, contact: $('#stContact').value}}); SITE = r.site; workspaceName = nm; $('#siteName').textContent = nm; toast('Site settings saved', 'ok'); route(); } catch (e) { toast(e.message, 'err'); } };
|
|
1835
1835
|
const ntEx = $('#ntExample'); if (ntEx) ntEx.onclick = () => { $('#ntCfg').value = JSON.stringify({channels: [{name: 'ops-hook', kind: 'webhook', url: 'https://hooks.example.com/gea', headers: {}}, {name: 'mail', kind: 'smtp', host: 'smtp.example.com', port: 587, starttls: true, from: 'gea@example.com', to: ['operations@example.com'], user: 'gea', password_env: 'GEA_SMTP_PASSWORD'}], rules: [{event: 'alarm.activated', priority: ['P1'], channels: ['ops-hook', 'mail']}, {event: 'job.failed', channels: ['ops-hook']}, {event: 'patch.down', channels: ['ops-hook', 'mail']}, {event: 'approval.pending', channels: ['mail']}], quiet_s: 300}, null, 1); $('details').open = true; };
|
|
1836
1836
|
$('#ntLoad').onclick = async () => { try { const c = await get('/api/config/notifications'); $('#ntCfg').value = JSON.stringify(c.current, null, 1); } catch (e) { toast('no committed notifications yet: ' + e.message, 'err'); } };
|
|
1837
1837
|
$('#ntSave').onclick = async () => { let c; try { c = JSON.parse($('#ntCfg').value); } catch (e) { return toast('not valid JSON: ' + e.message, 'err'); } try { const r = await post('/api/config/commit', {name: 'notifications', content: c, note: $('#ntNote').value}); toast(r.unchanged ? 'Unchanged' : `Committed notifications v${r.version}`, 'ok'); route(); } catch (e) { toast(e.message, 'err'); } };
|
|
@@ -1876,12 +1876,12 @@ VIEWS.welcome = async () => {
|
|
|
1876
1876
|
const step = o.workspace.n_wells === 0 ? (SITE.units ? 2 : 1) : (users.length < 2 ? 3 : 4);
|
|
1877
1877
|
const steps = ['Site', 'First well', 'People', 'First refresh'].map((t, i) => `<span class="${i + 1 === step ? 'on' : ''}">${i + 1}. ${t}</span>`).join('');
|
|
1878
1878
|
let h = `<h2>Setting up ${esc(workspaceName)}</h2>${help('welcome')}<div class="steps">${steps}</div>`;
|
|
1879
|
-
h += `<div class="card wizard"><h3>1. The site</h3><p class="small muted">
|
|
1879
|
+
h += `<div class="card wizard"><h3>1. The site</h3><p class="small muted">The site's name heads every report; how numbers and times are shown to everyone here, and the name on the home page.</p><div class="row"><label>Site name (on every report)<input id="wSiteName" maxlength="80" value="${esc(workspaceName)}"></label><label>Display name<input id="wName" value="${esc(SITE.display_name || workspaceName)}"></label><label>Units<select id="wUnits"><option value="field" ${(SITE.units || 'field') === 'field' ? 'selected' : ''}>field (psi, °F, ft)</option><option value="si" ${SITE.units === 'si' ? 'selected' : ''}>SI (kPa, °C, m)</option></select></label><label>Time zone<input id="wTz" value="${esc(SITE.time_zone || 'UTC')}" placeholder="UTC or America/Chicago"></label><button id="wSite" type="button">Save</button></div></div>`;
|
|
1880
1880
|
h += `<div class="card wizard"><h3>2. The first well</h3><p class="small muted">Upload a historian CSV, LAS, SEG-Y or operator table - or import a file from a folder you allow the dashboard to read.</p><div class="row"><label>Well name<input id="wWell" placeholder="A-12"></label><label>File<input id="wFile" type="file"></label><label>Gauge station MD (ft)<input id="wMd" type="number" placeholder="10000"></label><button id="wAdd" type="button">Add the well</button></div><p class="small">Or: <a href="#/files">browse the import roots</a>${fr.import.length ? '' : ' (none yet - add one below)'}.</p>${fr.import.length ? '' : `<div class="row"><label>Import root name<input id="wRootName" placeholder="historian"></label><label>Folder on this machine<input id="wRootPath" placeholder="C:\\data\\historian"></label><button class="secondary" id="wRoot" type="button">Allow this folder</button></div>`}</div>`;
|
|
1881
1881
|
h += `<div class="card wizard"><h3>3. People</h3><p class="small muted">${users.length} account(s). Operators run and acknowledge; approvers decide on well tests and re-fits; viewers only look.</p><div class="row"><label>Name<input id="wUser"></label><label>Password (8+)<input id="wPw" type="password"></label><label>Role<select id="wRole">${['operator', 'approver', 'viewer'].map(r => `<option>${r}</option>`).join('')}</select></label><button id="wUserAdd" type="button">Add</button></div></div>`;
|
|
1882
1882
|
h += `<div class="card wizard"><h3>4. The first refresh</h3><p class="small muted">Runs every calculation on every well and builds the reports. Takes a minute per well.</p><div class="row"><button id="wRefresh" type="button" ${o.workspace.n_wells ? '' : 'disabled'}>Refresh every report</button><button class="secondary" id="wDone" type="button">Finish the guide</button></div></div>`;
|
|
1883
1883
|
$('#main').innerHTML = h;
|
|
1884
|
-
$('#wSite').onclick = async () => { try { const r = await post('/api/site', {site: {display_name: $('#wName').value, units: $('#wUnits').value, time_zone: $('#wTz').value}}); SITE = r.site; toast('Saved', 'ok'); route(); } catch (e) { toast(e.message, 'err'); } };
|
|
1884
|
+
$('#wSite').onclick = async () => { try { const nm = $('#wSiteName').value.trim(); const r = await post('/api/site', {site: {...(nm && nm !== workspaceName ? {name: nm} : {}), display_name: ($('#wName').value === workspaceName && nm) ? nm : $('#wName').value, units: $('#wUnits').value, time_zone: $('#wTz').value}}); SITE = r.site; if (nm) { workspaceName = nm; $('#siteName').textContent = nm; } toast('Saved', 'ok'); route(); } catch (e) { toast(e.message, 'err'); } };
|
|
1885
1885
|
$('#wAdd').onclick = async () => { const f = $('#wFile').files[0]; if (!f) return toast('Choose a file', 'err'); try { const b64 = await readFile(f); await post('/api/wells/file', {display: $('#wWell').value || f.name, filename: f.name, content_b64: b64, station_md: $('#wMd').value ? +$('#wMd').value : null}); toast('Well added', 'ok'); route(); } catch (e) { toast(e.message, 'err'); } };
|
|
1886
1886
|
const wr = $('#wRoot'); if (wr) wr.onclick = async () => { try { await post('/api/files/roots/add', {which: 'import', name: $('#wRootName').value, path: $('#wRootPath').value}); toast('Folder allowed', 'ok'); route(); } catch (e) { toast(e.message, 'err'); } };
|
|
1887
1887
|
$('#wUserAdd').onclick = async () => { try { await post('/api/users/add', {name: $('#wUser').value, password: $('#wPw').value, role: $('#wRole').value}); toast('User added', 'ok'); route(); } catch (e) { toast(e.message, 'err'); } };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gea-program
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.66.0
|
|
4
4
|
Summary: GEA-Program: downhole gauge monitoring - canonical measurement records, quality rules, drift evaluation with a re-fit change log, well-test validation, alarm management, model cards, store-and-forward, monthly SLA measurement, FAT/SAT protocols and a dashboard, generated from live objects in the client's reporting outline.
|
|
5
5
|
Author: Daniel T. Murphy
|
|
6
6
|
License: MPL-2.0
|
|
@@ -1426,11 +1426,12 @@ attaches the zips to the GitHub release of that tag.
|
|
|
1426
1426
|
|
|
1427
1427
|
### The Windows installer
|
|
1428
1428
|
|
|
1429
|
-
Every release also carries `GEA-Program-Setup-0.
|
|
1429
|
+
Every release also carries `GEA-Program-Setup-0.66.0.exe` (for 0.66.0): the
|
|
1430
1430
|
same Windows kit installed like any Windows program, for the signed-in user
|
|
1431
1431
|
alone and with no administrator rights (`%LOCALAPPDATA%\Programs\GEA-Program`).
|
|
1432
1432
|
It asks for the site workspace (an existing one such as `C:\site` is used as
|
|
1433
|
-
it is
|
|
1433
|
+
it is, its name included; a new one is made with the site name it asks for,
|
|
1434
|
+
which heads every report), runs the kit's `install.cmd` with no network, and adds Start-menu and
|
|
1434
1435
|
desktop shortcuts, an Add/Remove Programs entry and, when chosen, a start at
|
|
1435
1436
|
sign-in. The shortcut **GEA-Program** starts the control panel when it is not
|
|
1436
1437
|
running and opens it in Microsoft Edge's app window (its own window and
|
|
@@ -1442,7 +1443,7 @@ it, removes the program and leaves the workspace. Silent, for a site's
|
|
|
1442
1443
|
software deployment:
|
|
1443
1444
|
|
|
1444
1445
|
```
|
|
1445
|
-
GEA-Program-Setup-0.
|
|
1446
|
+
GEA-Program-Setup-0.66.0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /WORKSPACE="C:\site" /SITENAME="Pad 3" /TASKS="desktopicon"
|
|
1446
1447
|
```
|
|
1447
1448
|
|
|
1448
1449
|
The setup is built by Inno Setup 6 from `tools/installer.iss` in the same
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "gea-program"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.66.0"
|
|
8
8
|
description = "GEA-Program: downhole gauge monitoring - canonical measurement records, quality rules, drift evaluation with a re-fit change log, well-test validation, alarm management, model cards, store-and-forward, monthly SLA measurement, FAT/SAT protocols and a dashboard, generated from live objects in the client's reporting outline."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/agassiz77_canada_temperature.provenance.json
RENAMED
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/barbados_110_consolidation.provenance.json
RENAMED
|
File without changes
|
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/bengal_u1452_grain_size.provenance.json
RENAMED
|
File without changes
|
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/blake_164_methane_isotopes.provenance.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json
RENAMED
|
File without changes
|
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json
RENAMED
|
File without changes
|
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json
RENAMED
|
File without changes
|
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json
RENAMED
|
File without changes
|
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json
RENAMED
|
File without changes
|
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/fram_909_organic_petrography.provenance.json
RENAMED
|
File without changes
|
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gea_program-0.65.0 → gea_program-0.66.0}/gea/catalog/gisp2_greenland_temperature.provenance.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|