Skip to main content

oseda_cli/
puppeteer.rs

1// utils for puppeteer and chrome
2
3use std::{error::Error, process::Command};
4
5use inquire::Confirm;
6/// Checks whether headless Chrome has been installed on the users system via npx puppeteer
7///
8/// # Returns
9///
10/// - `bool` - Whether or not it has been installed
11pub fn is_puppeteer_chrome_installed() -> bool {
12    //puppeteer will install into cache directory
13    // this is differnt on different systems
14    // afaik, not even specific to just OS -> so I pulled in `dirs`
15    let mut path = match dirs::cache_dir() {
16        Some(p) => p,
17        None => return false,
18    };
19
20    // {cache}/puppeteer/chrome
21    path.push("puppeteer");
22    path.push("chrome");
23
24    if path.is_dir() {
25        if let Ok(entries) = std::fs::read_dir(&path) {
26            // if any folder present, should be installed
27            return entries
28                .filter_map(Result::ok)
29                .any(|entry| entry.path().is_dir());
30        }
31    }
32
33    false
34}
35
36/// Prompts the user for an installation of headless Chrome via. Puppeteer, installing it if they elect to proceed
37///
38/// # Returns
39///
40/// - `Result<(), Box<dyn Error>>`
41/// - Ok(()) if installation proceeds as normal
42/// - Err() if installation is aborted by user
43pub fn prompt_install_puppeteer_chrome() -> Result<(), Box<dyn Error>> {
44    println!("`oseda export` uses DeckTape to export your presentation");
45    println!("DeckTape needs chromium installed (puppeteer prefered");
46    println!("Puppeteer Chrome is not currently detected.");
47    let ans = Confirm::new("Would you like to install it and proceed?")
48        .with_default(false)
49        .prompt();
50
51    // let else my beloved
52    // gaurd clause
53    let Ok(true) = ans else {
54        return Err("DeckTape is required to proceed".into());
55    };
56
57    println!("Installing Puppeteer Chrome... (This may take several minutes, you will only need to install this once");
58
59    let chrome_install_output = Command::new("npx")
60        .args(["puppeteer", "browsers", "install", "chrome"])
61        .output()?;
62
63    if !chrome_install_output.status.success() {
64        return Err("Error: could not install puppeteer chrome".into());
65    }
66
67    Ok(())
68}