move GIS check to Python agent (#29)

This commit is contained in:
Josh Thomas 2024-12-12 23:32:52 -06:00 committed by GitHub
parent b993e35460
commit cff90ee869
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 80 additions and 102 deletions

View file

@ -1,5 +1,3 @@
use djls_ipc::v1::*;
use djls_ipc::{ProcessError, PythonProcess};
use std::fmt;
#[derive(Debug)]
@ -36,24 +34,6 @@ impl Apps {
pub fn iter(&self) -> impl Iterator<Item = &App> {
self.apps().iter()
}
pub fn check_installed(python: &mut PythonProcess, app: &str) -> Result<bool, ProcessError> {
let request = messages::Request {
command: Some(messages::request::Command::CheckAppInstalled(
check::AppInstalledRequest {
app_name: app.to_string(),
},
)),
};
let response = python.send(request).map_err(ProcessError::Transport)?;
match response.result {
Some(messages::response::Result::CheckAppInstalled(response)) => Ok(response.passed),
Some(messages::response::Result::Error(e)) => Err(ProcessError::Health(e.message)),
_ => Err(ProcessError::Response),
}
}
}
impl fmt::Display for Apps {

View file

@ -1,4 +1,3 @@
use crate::gis::{check_gis_setup, GISError};
use djls_ipc::v1::*;
use djls_ipc::IpcCommand;
use djls_ipc::{ProcessError, PythonProcess, TransportError};
@ -24,16 +23,24 @@ impl DjangoProject {
pub fn setup(mut python: PythonProcess) -> Result<Self, ProjectError> {
let py = Python::setup(&mut python)?;
if !check_gis_setup(&mut python)? {
eprintln!("Warning: GeoDjango detected but GDAL is not available.");
eprintln!("Django initialization will be skipped. Some features may be limited.");
eprintln!("To enable full functionality, please install GDAL and other GeoDjango prerequisites.");
match check::GeoDjangoPrereqsRequest::execute(&mut python)?.result {
Some(messages::response::Result::CheckGeodjangoPrereqs(response)) => {
if !response.passed {
eprintln!("Warning: GeoDjango detected but GDAL is not available.");
eprintln!(
"Django initialization will be skipped. Some features may be limited."
);
eprintln!("To enable full functionality, please install GDAL and other GeoDjango prerequisites.");
return Ok(Self {
py,
python,
version: String::new(),
});
return Ok(Self {
py,
python,
version: String::new(),
});
}
}
Some(messages::response::Result::Error(e)) => Err(ProcessError::Health(e.message))?,
_ => Err(ProcessError::Response)?,
}
let response = django::GetProjectInfoRequest::execute(&mut python)?;
@ -77,8 +84,6 @@ pub enum ProjectError {
DjangoNotFound,
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("GIS error: {0}")]
Gis(#[from] GISError),
#[error("JSON parsing error: {0}")]
Json(#[from] serde_json::Error),
#[error(transparent)]

View file

@ -1,26 +0,0 @@
use crate::apps::Apps;
use djls_ipc::{ProcessError, PythonProcess, TransportError};
use std::process::Command;
pub fn check_gis_setup(python: &mut PythonProcess) -> Result<bool, GISError> {
let has_geodjango = Apps::check_installed(python, "django.contrib.gis")?;
let gdal_is_installed = Command::new("gdalinfo")
.arg("--version")
.output()
.map(|output| output.status.success())
.unwrap_or(false);
Ok(!has_geodjango || gdal_is_installed)
}
#[derive(Debug, thiserror::Error)]
pub enum GISError {
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("JSON parsing error: {0}")]
Json(#[from] serde_json::Error),
#[error("Process error: {0}")]
Process(#[from] ProcessError),
#[error("Transport error: {0}")]
Transport(#[from] TransportError),
}

View file

@ -1,6 +1,5 @@
mod apps;
mod django;
mod gis;
mod templates;
pub use django::DjangoProject;

View file

@ -29,6 +29,22 @@ impl IpcCommand for v1::check::HealthRequest {
}
}
impl IpcCommand for v1::check::GeoDjangoPrereqsRequest {
fn into_request(&self) -> messages::Request {
messages::Request {
command: Some(messages::request::Command::CheckGeodjangoPrereqs(*self)),
}
}
fn from_response(response: messages::Response) -> Result<messages::Response, ProcessError> {
match response.result {
Some(messages::response::Result::CheckGeodjangoPrereqs(_)) => Ok(response),
Some(messages::response::Result::Error(e)) => Err(ProcessError::Health(e.message)),
_ => Err(ProcessError::Response),
}
}
}
impl IpcCommand for v1::python::GetEnvironmentRequest {
fn into_request(&self) -> messages::Request {
messages::Request {