Skip to content

Commit

Permalink
refactor(app): wait for app-ready before checking for updates
Browse files Browse the repository at this point in the history
  • Loading branch information
tymmesyde committed Jan 30, 2025
1 parent 7148d7f commit 69b957b
Showing 1 changed file with 141 additions and 113 deletions.
254 changes: 141 additions & 113 deletions src/stremio_app/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::{
process::{self, Command},

Check warning on line 10 in src/stremio_app/app.rs

View workflow job for this annotation

GitHub Actions / test

Diff in \\?\D:\a\stremio-shell-ng\stremio-shell-ng\src\stremio_app\app.rs
str,
sync::{Arc, Mutex},
thread, time,
thread, time::{self, Duration},
};
use url::Url;
use winapi::um::{winbase::CREATE_BREAKAWAY_FROM_JOB, winuser::WS_EX_TOPMOST};
Expand Down Expand Up @@ -133,6 +133,10 @@ impl MainWindow {
let web_tx_arg = web_tx.clone();
let web_tx_upd = web_tx.clone();
let web_rx = web_rx.clone();

let (updater_tx, updater_rx) = flume::unbounded::<String>();
let updater_tx_web = updater_tx.clone();

let command_clone = self.command.clone();

// Single application IPC
Expand All @@ -147,34 +151,44 @@ impl MainWindow {
let release_candidate = self.release_candidate;
let autoupdater_setup_file = self.autoupdater_setup_file.clone();
thread::spawn(move || loop {
let current_version = env!("CARGO_PKG_VERSION")
.parse()
.expect("Should always be valid");
let updater_endpoint = if let Some(ref endpoint) = autoupdater_endpoint {
endpoint.clone()
} else {
let mut rng = rand::thread_rng();
let index = rng.gen_range(0..UPDATE_ENDPOINT.len());
let mut url = Url::parse(UPDATE_ENDPOINT[index]).unwrap();
if release_candidate {
url.query_pairs_mut().append_pair("rc", "true");
let check_for_update = || {
let current_version = env!("CARGO_PKG_VERSION")
.parse()
.expect("Should always be valid");

let updater_endpoint = if let Some(ref endpoint) = autoupdater_endpoint {
endpoint.clone()
} else {
let mut rng = rand::thread_rng();
let index = rng.gen_range(0..UPDATE_ENDPOINT.len());
let mut url = Url::parse(UPDATE_ENDPOINT[index]).unwrap();
if release_candidate {
url.query_pairs_mut().append_pair("rc", "true");
}
url

Check warning on line 168 in src/stremio_app/app.rs

View workflow job for this annotation

GitHub Actions / test

Diff in \\?\D:\a\stremio-shell-ng\stremio-shell-ng\src\stremio_app\app.rs
};

let updater = updater::Updater::new(current_version, &updater_endpoint, force_update);
match updater.autoupdate() {
Ok(Some(update)) => {
println!("New version ready to install v{}", update.version);
let mut autoupdater_setup_file = autoupdater_setup_file.lock().unwrap();
*autoupdater_setup_file = Some(update.file.clone());
web_tx_upd.send(RPCResponse::update_available()).ok();
}
Ok(None) => println!("No new updates found"),
Err(e) => eprintln!("Failed to fetch updates: {e}"),
}
url
};
let updater = updater::Updater::new(current_version, &updater_endpoint, force_update);

match updater.autoupdate() {
Ok(Some(update)) => {
println!("New version ready to install v{}", update.version);
let mut autoupdater_setup_file = autoupdater_setup_file.lock().unwrap();
*autoupdater_setup_file = Some(update.file.clone());
web_tx_upd.send(RPCResponse::update_available()).ok();
}
Ok(None) => println!("No new updates found"),
Err(e) => eprintln!("Failed to fetch updates: {e}"),
}
updater_rx
.try_iter()
.for_each(|message| match message.as_str() {
"check_for_update" => check_for_update(),
_ => {}
});

thread::sleep(time::Duration::from_secs(UPDATE_INTERVAL));
thread::sleep(Duration::from_millis(10));
}); // thread

if let Ok(mut listener) = PipeServer::bind(socket_path) {
Expand All @@ -201,109 +215,123 @@ impl MainWindow {
.for_each(drop);
}); // thread

let mut last_update_check = time::Instant::now();
let toggle_fullscreen_sender = self.toggle_fullscreen_notice.sender();
let quit_sender = self.quit_notice.sender();
let hide_splash_sender = self.hide_splash_notice.sender();
let focus_sender = self.focus_notice.sender();
let autoupdater_setup_mutex = self.autoupdater_setup_file.clone();
thread::spawn(move || loop {
if let Some(msg) = web_rx
.recv()
.ok()
.and_then(|s| serde_json::from_str::<RPCRequest>(&s).ok())
{
match msg.get_method() {
// The handshake. Here we send some useful data to the WEB UI
None if msg.is_handshake() => {
web_tx_web.send(RPCResponse::get_handshake()).ok();
}
Some("win-set-visibility") => toggle_fullscreen_sender.notice(),
Some("quit") => quit_sender.notice(),
Some("app-ready") => {
hide_splash_sender.notice();
web_tx_web
.send(RPCResponse::visibility_change(true, 1, false))
.ok();
let command_ref = command_clone.clone();
if !command_ref.is_empty() {
web_tx_web.send(RPCResponse::open_media(command_ref)).ok();
let now = time::Instant::now();
if now > (last_update_check + time::Duration::from_secs(UPDATE_INTERVAL)) {
last_update_check = now;
updater_tx_web
.send("check_for_update".to_owned())
.expect("Failed to send value to updater channel");
}

web_rx

Check warning on line 233 in src/stremio_app/app.rs

View workflow job for this annotation

GitHub Actions / test

Diff in \\?\D:\a\stremio-shell-ng\stremio-shell-ng\src\stremio_app\app.rs
.try_iter()
.map(|message| serde_json::from_str::<RPCRequest>(&message))
.for_each(|result| if let Ok(request) = result {
match request.get_method() {
// The handshake. Here we send some useful data to the WEB UI
None if request.is_handshake() => {
web_tx_web.send(RPCResponse::get_handshake()).ok();
}
}
Some("app-error") => {
hide_splash_sender.notice();
if let Some(arg) = msg.get_params() {
// TODO: Make this modal dialog
eprintln!("Web App Error: {}", arg);
Some("win-set-visibility") => toggle_fullscreen_sender.notice(),
Some("quit") => quit_sender.notice(),
Some("app-ready") => {
hide_splash_sender.notice();
web_tx_web
.send(RPCResponse::visibility_change(true, 1, false))
.ok();
updater_tx_web
.send("check_for_update".to_owned())
.expect("Failed to send value to updater channel");

let command_ref = command_clone.clone();
if !command_ref.is_empty() {
web_tx_web.send(RPCResponse::open_media(command_ref)).ok();
}
}
}
Some("open-external") => {
if let Some(arg) = msg.get_params() {
// FIXME: THIS IS NOT SAFE BY ANY MEANS
// open::that("calc").ok(); does exactly that
let arg = arg.as_str().unwrap_or("");
let arg_lc = arg.to_lowercase();
if arg_lc.starts_with("http://")
|| arg_lc.starts_with("https://")
|| arg_lc.starts_with("rtp://")
|| arg_lc.starts_with("rtps://")
|| arg_lc.starts_with("ftp://")
|| arg_lc.starts_with("ipfs://")
{
open::that(arg).ok();
Some("app-error") => {
hide_splash_sender.notice();
if let Some(arg) = request.get_params() {
// TODO: Make this modal dialog
eprintln!("Web App Error: {}", arg);
}
}
}
Some("win-focus") => {
focus_sender.notice();
}
Some("autoupdater-notif-clicked") => {
// We've shown the "Update Available" notification
// and the user clicked on "Restart And Update"
let autoupdater_setup_file =
autoupdater_setup_mutex.lock().unwrap().clone();
match autoupdater_setup_file {
Some(file_path) => {
println!("Running the setup at {:?}", file_path);
Some("open-external") => {
if let Some(arg) = request.get_params() {
// FIXME: THIS IS NOT SAFE BY ANY MEANS
// open::that("calc").ok(); does exactly that
let arg = arg.as_str().unwrap_or("");
let arg_lc = arg.to_lowercase();
if arg_lc.starts_with("http://")
|| arg_lc.starts_with("https://")
|| arg_lc.starts_with("rtp://")
|| arg_lc.starts_with("rtps://")
|| arg_lc.starts_with("ftp://")
|| arg_lc.starts_with("ipfs://")
{
open::that(arg).ok();
}
}
}
Some("win-focus") => {
focus_sender.notice();
}
Some("autoupdater-notif-clicked") => {
// We've shown the "Update Available" notification
// and the user clicked on "Restart And Update"
let autoupdater_setup_file =
autoupdater_setup_mutex.lock().unwrap().clone();
match autoupdater_setup_file {
Some(file_path) => {
println!("Running the setup at {:?}", file_path);

let command = Command::new(file_path)
.args([
"/SILENT",
"/NOCANCEL",
"/FORCECLOSEAPPLICATIONS",
"/TASKS=runapp",
])
.creation_flags(CREATE_BREAKAWAY_FROM_JOB)
.stdin(process::Stdio::null())
.stdout(process::Stdio::null())
.stderr(process::Stdio::null())
.spawn();
let command = Command::new(file_path)
.args([
"/SILENT",
"/NOCANCEL",
"/FORCECLOSEAPPLICATIONS",
"/TASKS=runapp",
])
.creation_flags(CREATE_BREAKAWAY_FROM_JOB)
.stdin(process::Stdio::null())
.stdout(process::Stdio::null())
.stderr(process::Stdio::null())
.spawn();

match command {
Ok(process) => {
println!("Updater started. (PID {:?})", process.id());
quit_sender.notice();
}
Err(err) => eprintln!("Updater couldn't be started: {err}"),
};
}
_ => {
println!("Cannot obtain the setup file path");
match command {
Ok(process) => {
println!("Updater started. (PID {:?})", process.id());
quit_sender.notice();
}
Err(err) => eprintln!("Updater couldn't be started: {err}"),
};
}
_ => {
println!("Cannot obtain the setup file path");
}
}
}
Some(player_command) if player_command.starts_with("mpv-") => {
let resp_json = serde_json::to_string(
&request.args.expect("Cannot have method without args"),
)
.expect("Cannot build response");
player_tx.send(resp_json).ok();
}
Some(unknown) => {
eprintln!("Unsupported command {}({:?})", unknown, request.get_params())
}
None => {}
}
Some(player_command) if player_command.starts_with("mpv-") => {
let resp_json = serde_json::to_string(
&msg.args.expect("Cannot have method without args"),
)
.expect("Cannot build response");
player_tx.send(resp_json).ok();
}
Some(unknown) => {
eprintln!("Unsupported command {}({:?})", unknown, msg.get_params())
}
None => {}
}
} // recv
});

thread::sleep(Duration::from_millis(10));
}); // thread
}
fn on_min_max(&self, data: &nwg::EventData) {
Expand Down

0 comments on commit 69b957b

Please sign in to comment.