Skip to main content

bellande_node_importance/
bellande_node_importance.rs

1// Copyright (C) 2024 Bellande Robotics Sensors Research Innovation Center, Ronaldson Bellande
2
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11// GNU General Public License for more details.
12
13// You should have received a copy of the GNU General Public License
14// along with this program.  If not, see <https://www.gnu.org/licenses/>.
15
16use reqwest;
17use serde_json::{json, Value};
18use std::error::Error;
19use std::path::{Path, PathBuf};
20use std::process::{self, Command};
21use structopt::StructOpt;
22
23#[derive(StructOpt, Debug)]
24#[structopt(
25    name = "bellande_node_importance",
26    about = "Bellande Node Importance Tool"
27)]
28struct Opt {
29    #[structopt(
30        long,
31        help = "Node to evaluate as JSON object with coordinates and segment"
32    )]
33    node: String,
34
35    #[structopt(long, help = "List of recent nodes as JSON array")]
36    recent_nodes: String,
37
38    #[structopt(long, help = "Dictionary of important nodes by segment as JSON object")]
39    important_nodes: String,
40
41    #[structopt(long, help = "Dictionary of adjacent segments as JSON object")]
42    adjacent_segments: String,
43
44    #[structopt(long, help = "Grid steps for each dimension as JSON array")]
45    grid_steps: String,
46
47    #[structopt(
48        long,
49        help = "Minimum required segment coverage ratio",
50        default_value = "0.5"
51    )]
52    min_segment_coverage: f64,
53
54    #[structopt(long, help = "Use local executable instead of API")]
55    use_executable: bool,
56}
57
58pub async fn make_bellande_node_importance_request(
59    node: Value,
60    recent_nodes: Value,
61    important_nodes: Value,
62    adjacent_segments: Value,
63    grid_steps: Value,
64    min_segment_coverage: f64,
65) -> Result<Value, Box<dyn Error>> {
66    let client = reqwest::Client::new();
67    let url = "https://bellande-robotics-sensors-research-innovation-center.org/api/Bellande_Node_Importance/node_importance";
68
69    let payload = json!({
70        "node": node,
71        "nodes": recent_nodes,
72        "important_nodes": important_nodes,
73        "adjacent_segments": adjacent_segments,
74        "grid_steps": grid_steps,
75        "min_segment_coverage": min_segment_coverage,
76        "auth": {
77            "authorization_key": "bellande_web_api_opensource"
78        }
79    });
80
81    let response = client
82        .post(url)
83        .header("accept", "application/json")
84        .header("Content-Type", "application/json")
85        .json(&payload)
86        .send()
87        .await?
88        .json::<Value>()
89        .await?;
90
91    Ok(response)
92}
93
94pub async fn make_bellande_node_importance_request_local(
95    url: &str,
96    node: Value,
97    recent_nodes: Value,
98    important_nodes: Value,
99    adjacent_segments: Value,
100    grid_steps: Value,
101    min_segment_coverage: f64,
102) -> Result<Value, Box<dyn Error>> {
103    let client = reqwest::Client::new();
104    let url = url;
105
106    let payload = json!({
107        "node": node,
108        "nodes": recent_nodes,
109        "important_nodes": important_nodes,
110        "adjacent_segments": adjacent_segments,
111        "grid_steps": grid_steps,
112        "min_segment_coverage": min_segment_coverage,
113        "auth": {
114            "authorization_key": "bellande_web_api_opensource"
115        }
116    });
117
118    let response = client
119        .post(url)
120        .header("accept", "application/json")
121        .header("Content-Type", "application/json")
122        .json(&payload)
123        .send()
124        .await?
125        .json::<Value>()
126        .await?;
127
128    Ok(response)
129}
130
131pub fn get_executable_path() -> PathBuf {
132    if cfg!(target_os = "windows") {
133        Path::new(env!("CARGO_MANIFEST_DIR")).join("Bellande_Node_Importance.exe")
134    } else {
135        Path::new(env!("CARGO_MANIFEST_DIR")).join("Bellande_Node_Importance")
136    }
137}
138
139pub fn run_bellande_node_importance_executable(
140    node: &str,
141    recent_nodes: &str,
142    important_nodes: &str,
143    adjacent_segments: &str,
144    grid_steps: &str,
145    min_segment_coverage: f64,
146) -> Result<(), Box<dyn Error>> {
147    let executable_path = get_executable_path();
148    let passcode = "bellande_node_importance_executable_access_key";
149
150    // Parse and validate input
151    let node_obj: Value = serde_json::from_str(node)?;
152    let grid_steps_list: Value = serde_json::from_str(grid_steps)?;
153
154    // Validate dimensions
155    if let (Some(coords), Some(steps)) = (node_obj["coords"].as_array(), grid_steps_list.as_array())
156    {
157        if coords.len() != steps.len() {
158            return Err(format!(
159                "Node coordinates must match grid steps dimensions ({})",
160                steps.len()
161            )
162            .into());
163        }
164    }
165
166    // Prepare and run command
167    let output = Command::new(executable_path)
168        .args(&[
169            passcode,
170            node,
171            recent_nodes,
172            important_nodes,
173            adjacent_segments,
174            grid_steps,
175            &min_segment_coverage.to_string(),
176        ])
177        .output()?;
178
179    if output.status.success() {
180        println!("{}", String::from_utf8_lossy(&output.stdout));
181        Ok(())
182    } else {
183        Err(format!(
184            "Process failed: {}",
185            String::from_utf8_lossy(&output.stderr)
186        )
187        .into())
188    }
189}