Run the one-step importer from the UI. Don't attempt a proper loading

screen yet. #523

Not working yet; one_step assumes paths to binaries, and it's now wrong.
This commit is contained in:
Dustin Carlino 2021-03-13 13:33:27 -08:00
parent c252e4a82d
commit 4e665b6214
2 changed files with 101 additions and 20 deletions

View File

@ -11,6 +11,7 @@ use abstutil::{must_run_cmd, CmdArgs};
fn main() -> Result<()> {
let mut args = CmdArgs::new();
let geojson_path = args.required_free();
let drive_on_left = args.enabled("--drive_on_left");
args.done();
// TODO Assumes the binaries are in hardcoded target directories... we could be smarter and
@ -18,6 +19,7 @@ fn main() -> Result<()> {
// Convert to a boundary polygon. This tool reads from STDIN.
{
println!("Converting GeoJSON to Osmosis boundary");
let geojson = abstio::slurp_file(geojson_path)?;
let mut cmd = Command::new("./target/debug/geojson_to_osmosis")
.stdin(Stdio::piped())
@ -29,17 +31,18 @@ fn main() -> Result<()> {
// What file should we download?
let url = {
println!("Figuring out what Geofabrik file contains your boundary");
let out = Command::new("./target/debug/pick_geofabrik")
.arg("boundary0.poly")
.output()?;
assert!(out.status.success());
String::from_utf8(out.stdout)?
};
println!("go dl {}", url);
// Download it!
// TODO This is timing out. Also, really could use progress bars.
{
println!("Downloading {}", url);
let resp = reqwest::blocking::get(&url)?;
assert!(resp.status().is_success());
let bytes = resp.bytes()?;
@ -48,6 +51,7 @@ fn main() -> Result<()> {
}
// Clip it
println!("Clipping osm.pbf file to your boundary");
must_run_cmd(
Command::new("./target/release/clip_osm")
.arg("--pbf=raw.pbf")
@ -56,11 +60,16 @@ fn main() -> Result<()> {
);
// Import!
must_run_cmd(
Command::new("./target/release/importer")
.arg("--oneshot=clipped.osm")
.arg("--oneshot_clip=boundary0.poly"),
);
{
let mut cmd = Command::new("./target/release/importer");
cmd.arg("--oneshot=clipped.osm");
cmd.arg("--oneshot_clip=boundary0.poly");
if drive_on_left {
cmd.arg("--oneshot_drive_on_left");
}
println!("Running importer");
must_run_cmd(&mut cmd);
}
Ok(())
}

View File

@ -1,9 +1,12 @@
use std::io::Write;
use std::process::Command;
use anyhow::Result;
use clipboard::{ClipboardContext, ClipboardProvider};
use widgetry::{EventCtx, Line, Panel, SimpleState, State, TextExt, Toggle, Transition, Widget};
use widgetry::{
EventCtx, GfxCtx, Line, Panel, SimpleState, State, Text, TextExt, Toggle, Transition, Widget,
};
use crate::tools::{open_browser, PopupMsg};
use crate::AppLike;
@ -55,7 +58,13 @@ impl ImportCity {
}
impl<A: AppLike + 'static> SimpleState<A> for ImportCity {
fn on_click(&mut self, ctx: &mut EventCtx, _: &mut A, x: &str, panel: &Panel) -> Transition<A> {
fn on_click(
&mut self,
ctx: &mut EventCtx,
app: &mut A,
x: &str,
panel: &Panel,
) -> Transition<A> {
match x {
"close" => Transition::Pop,
"Alternate instructions" => {
@ -67,22 +76,32 @@ impl<A: AppLike + 'static> SimpleState<A> for ImportCity {
Transition::Keep
}
"Import the area from your clipboard" => {
let drive_on_left = !panel.is_checked("driving side");
let mut cmd = Command::new("../target/debug/one_step_import");
cmd.arg("boundary.geojson");
if !panel.is_checked("driving side") {
cmd.arg("--drive_on_left");
}
match grab_geojson_from_clipboard() {
Ok(()) => {
println!("drive on left? {}", drive_on_left);
Transition::Keep
}
Err(err) => {
return Transition::Push(PopupMsg::new(
Ok(()) => Transition::Multi(vec![
Transition::Replace(RunCommand::new(ctx, app, cmd)),
Transition::Push(PopupMsg::new(
ctx,
"Error",
"Ready to import",
vec![
"Couldn't get GeoJSON from your clipboard".to_string(),
err.to_string(),
"The import will now download what's needed and run in the \
background.",
"No progress bar or way to cancel yet, sorry.",
],
));
}
)),
]),
Err(err) => Transition::Push(PopupMsg::new(
ctx,
"Error",
vec![
"Couldn't get GeoJSON from your clipboard".to_string(),
err.to_string(),
],
)),
}
}
_ => unreachable!(),
@ -110,3 +129,56 @@ fn grab_geojson_from_clipboard() -> Result<()> {
write!(f, "{}", contents)?;
Ok(())
}
struct RunCommand {
cmd: Command,
panel: Panel,
}
impl RunCommand {
fn new<A: AppLike + 'static>(ctx: &mut EventCtx, _: &A, cmd: Command) -> Box<dyn State<A>> {
let txt = Text::from(Line("Running command..."));
let panel = ctx.make_loading_screen(txt);
Box::new(RunCommand { cmd, panel })
}
}
impl<A: AppLike + 'static> State<A> for RunCommand {
fn event(&mut self, ctx: &mut EventCtx, _: &mut A) -> Transition<A> {
// TODO Blocking...
// TODO Combo stdout/stderr
info!("Running cmd {:?}", self.cmd);
let (ok, messages) = match self
.cmd
.output()
.map_err(|err| anyhow::Error::new(err))
.and_then(|out| {
let status = out.status;
String::from_utf8(out.stdout)
.map(|stdout| (status, stdout))
.map_err(|err| err.into())
}) {
Ok((status, stdout)) => {
// TODO Split by newlines
if status.success() {
(true, vec!["Output:".to_string(), stdout])
} else {
(false, vec!["Command failed. Output:".to_string(), stdout])
}
}
Err(err) => (
false,
vec!["Couldn't run command".to_string(), err.to_string()],
),
};
Transition::Replace(PopupMsg::new(
ctx,
if ok { "Success" } else { "Failure" },
messages,
))
}
fn draw(&self, g: &mut GfxCtx, _: &A) {
self.panel.draw(g);
}
}