From 6fa118166d94365a989e4ea8cdfa47b900f3d06b Mon Sep 17 00:00:00 2001 From: CEbbinghaus Date: Sun, 22 Sep 2024 15:08:10 +1000 Subject: [PATCH 1/4] Fixed bug preventing non steam games from getting added --- backend/src/api.rs | 85 +++++++++++++++++++++++++--------- backend/src/log.rs | 31 +++++++++++-- lib/src/backend.ts | 4 +- src/components/CardActions.tsx | 17 +++++-- src/modals/EditCardModal.tsx | 2 +- 5 files changed, 106 insertions(+), 33 deletions(-) diff --git a/backend/src/api.rs b/backend/src/api.rs index 9e28919..6b303d5 100644 --- a/backend/src/api.rs +++ b/backend/src/api.rs @@ -56,12 +56,16 @@ pub(crate) async fn version() -> impl Responder { #[get("/health")] #[instrument] pub(crate) async fn health() -> impl Responder { + trace!("HTTP GET /health"); + HttpResponse::Ok() } #[get("/listen")] #[instrument] pub(crate) async fn listen(sender: web::Data>) -> Result { + trace!("HTTP GET /listen"); + let event_stream = BroadcastStream::new(sender.subscribe()).map(|res| match res { Err(_) => Err(Error::from_str("Subscriber Closed")), Ok(value) => Ok(Event::new(value).into()), @@ -72,17 +76,21 @@ pub(crate) async fn listen(sender: web::Data>) -> Result>) -> impl Responder { + trace!("HTTP GET /list"); + web::Json(datastore.list_cards_with_games()) } #[get("/list/games/{card_id}")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn list_games_for_card( card_id: web::Path, datastore: web::Data>, ) -> Result { + trace!("HTTP GET /list/games/{card_id}"); + match datastore.get_games_on_card(&card_id) { Ok(value) => Ok(web::Json(value)), Err(err) => Err(actix_web::Error::from(err)), @@ -90,11 +98,13 @@ pub(crate) async fn list_games_for_card( } #[get("/list/cards/{game_id}")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn list_cards_for_game( game_id: web::Path, datastore: web::Data>, ) -> Result { + trace!("HTTP GET /list/cards/{game_id}"); + match datastore.get_cards_for_game(&game_id) { Ok(value) => Ok(web::Json(value)), Err(err) => Err(actix_web::Error::from(err)), @@ -102,10 +112,12 @@ pub(crate) async fn list_cards_for_game( } #[get("/current")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn get_current_card_and_games( datastore: web::Data>, ) -> Result> { + trace!("HTTP GET /current"); + if !is_card_inserted() { return Ok(Either::Right( HttpResponseBuilder::new(StatusCode::NO_CONTENT) @@ -125,8 +137,10 @@ pub(crate) async fn get_current_card_and_games( } #[get("/current/card")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn get_current_card(datastore: web::Data>) -> Result { + trace!("HTTP GET /current/card"); + if !is_card_inserted() { return Err(Error::from_str("No card is inserted").into()); } @@ -139,6 +153,8 @@ pub(crate) async fn get_current_card(datastore: web::Data>) -> Result #[get("/current/id")] #[instrument] pub(crate) async fn get_current_card_id() -> Result { + trace!("HTTP GET /current/id"); + if !is_card_inserted() { return Err(Error::from_str("No card is inserted").into()); } @@ -147,10 +163,12 @@ pub(crate) async fn get_current_card_id() -> Result { } #[get("/current/games")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn get_games_on_current_card( datastore: web::Data>, ) -> Result { + trace!("HTTP GET /current/games"); + if !is_card_inserted() { return Err(Error::from_str("No card is inserted").into()); } @@ -164,13 +182,15 @@ pub(crate) async fn get_games_on_current_card( } #[post("/card/{id}")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn create_card( id: web::Path, body: web::Json, datastore: web::Data>, sender: web::Data>, ) -> Result { + trace!("HTTP POST /card/{id}"); + if *id != body.uid { return Err(Error::from_str("uid did not match id provided").into()); } @@ -185,18 +205,18 @@ pub(crate) async fn create_card( false => datastore.add_card(id.into_inner(), body.into_inner()), } - trace!("Sending Updated event"); _ = sender.send(CardEvent::Updated); Ok(HttpResponse::Ok()) } #[delete("/card/{id}")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn delete_card( id: web::Path, datastore: web::Data>, sender: web::Data>, ) -> Result { + trace!("HTTP DELETE /card/{id}"); datastore.remove_element(&id)?; trace!("Sending Updated event"); @@ -205,21 +225,24 @@ pub(crate) async fn delete_card( } #[get("/card/{id}")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn get_card( id: web::Path, datastore: web::Data>, ) -> Result { + trace!("HTTP GET /card/{id}"); Ok(web::Json(datastore.get_card(&id)?)) } #[post("/cards")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn update_cards( body: web::Json>, datastore: web::Data>, sender: web::Data>, ) -> Result { + trace!("HTTP POST /cards"); + for card in body.iter() { let card = card.to_owned(); @@ -240,18 +263,21 @@ pub(crate) async fn update_cards( } #[get("/cards")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn list_cards(datastore: web::Data>) -> impl Responder { + trace!("HTTP GET /cards"); web::Json(datastore.list_cards()) } #[post("/game/{id}")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn create_game( id: web::Path, body: web::Json, datastore: web::Data>, ) -> Result { + trace!("HTTP POST /game/{id}"); + if *id != body.uid { return Err(Error::from_str("uid did not match id provided").into()); } @@ -267,38 +293,43 @@ pub(crate) async fn create_game( } #[delete("/game/{id}")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn delete_game( id: web::Path, datastore: web::Data>, ) -> Result { + trace!("HTTP DELETE /game/{id}"); datastore.remove_element(&id)?; Ok(HttpResponse::Ok()) } #[get("/game/{id}")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn get_game( id: web::Path, datastore: web::Data>, ) -> Result { + trace!("HTTP GET /game/{id}"); Ok(web::Json(datastore.get_game(&id)?)) } #[get("/games")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn list_games(datastore: web::Data>) -> impl Responder { + trace!("HTTP GET /games"); web::Json(datastore.list_games()) } #[allow(clippy::async_yields_async)] #[post("/games")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn create_games( body: web::Json>, datastore: web::Data>, ) -> impl Responder { + trace!("HTTP POST /games"); + for game in body.iter() { let mut game = game.to_owned(); @@ -325,12 +356,14 @@ pub struct ManyLinkBody { } #[post("/link")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn create_link( body: web::Json, datastore: web::Data>, sender: web::Data>, ) -> Result { + trace!("HTTP POST /link"); + datastore.link(&body.game_id, &body.card_id)?; trace!("Sending Updated event"); @@ -339,12 +372,14 @@ pub(crate) async fn create_link( } #[post("/linkmany")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn create_links( body: web::Json, datastore: web::Data>, sender: web::Data>, ) -> Result { + trace!("HTTP POST /linkmany"); + let data = body.into_inner(); for game_id in data.game_ids.iter() { datastore.link(game_id, &data.card_id)?; @@ -356,12 +391,14 @@ pub(crate) async fn create_links( } #[post("/unlink")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn delete_link( body: web::Json, datastore: web::Data>, sender: web::Data>, ) -> Result { + trace!("HTTP POST /unlink"); + datastore.unlink(&body.game_id, &body.card_id)?; trace!("Sending Updated event"); @@ -370,12 +407,14 @@ pub(crate) async fn delete_link( } #[post("/unlinkmany")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn delete_links( body: web::Json, datastore: web::Data>, sender: web::Data>, ) -> Result { + trace!("HTTP POST /unlinkmany"); + let data = body.into_inner(); for game_id in data.game_ids.iter() { datastore.unlink(game_id, &data.card_id)?; @@ -387,8 +426,10 @@ pub(crate) async fn delete_links( } #[post("/save")] -#[instrument] +#[instrument(skip(datastore))] pub(crate) async fn save(datastore: web::Data>) -> Result { + trace!("HTTP POST /save"); + datastore.write_to_file()?; Ok(HttpResponse::Ok()) diff --git a/backend/src/log.rs b/backend/src/log.rs index b282200..1ccd6c6 100644 --- a/backend/src/log.rs +++ b/backend/src/log.rs @@ -2,7 +2,16 @@ use crate::cfg::CONFIG; use crate::{get_file_path_and_create_directory, LOG_DIR}; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; -use tracing_subscriber::Layer; +use tracing_subscriber::{filter, Layer}; + +const IGNORED_MODULES: [&'static str; 6] = [ + "actix_http::h1::decoder", + "actix_http::h1::dispatcher", + "actix_http::h1::timer", + "actix_server::signals", + "actix_server::worker", + "mio::poll", +]; pub fn create_subscriber() { let log_file_path = get_file_path_and_create_directory(&CONFIG.log_file, &LOG_DIR) @@ -19,13 +28,29 @@ pub fn create_subscriber() { .with_writer(file) .with_filter(tracing_subscriber::filter::LevelFilter::from_level( CONFIG.log_level, - )); + )) + .with_filter(filter::filter_fn(|metadata| { + metadata + .module_path() + .is_some_and(|module| !IGNORED_MODULES.contains(&module)) + })); let subscriber = tracing_subscriber::registry().with(file_writer); if cfg!(debug_assertions) { subscriber - .with(tracing_subscriber::fmt::layer().pretty()) + .with( + tracing_subscriber::fmt::layer() + .pretty() + .with_filter(tracing_subscriber::filter::LevelFilter::from_level( + log_level, + )) + .with_filter(filter::filter_fn(|metadata| { + metadata + .module_path() + .is_some_and(|module| !IGNORED_MODULES.contains(&module)) + })), + ) .init(); } else { subscriber.init(); diff --git a/lib/src/backend.ts b/lib/src/backend.ts index 949f09a..577e167 100644 --- a/lib/src/backend.ts +++ b/lib/src/backend.ts @@ -156,10 +156,10 @@ export async function fetchCardsForGame({ url, logger, gameId }: FetchProps & { } export async function fetchCreateGame({ url, logger, game}: FetchProps & { game: Game }) { - await wrapFetch({ url: `${url}/game`, logger }, { + await wrapFetch({ url: `${url}/game/${game.uid}`, logger }, { method: "POST", ...ApplicationJsonHeaders, - body: JSON.stringify({game}), + body: JSON.stringify(game), }); } diff --git a/src/components/CardActions.tsx b/src/components/CardActions.tsx index 130a1dd..b8337eb 100644 --- a/src/components/CardActions.tsx +++ b/src/components/CardActions.tsx @@ -30,17 +30,24 @@ export function CardActionsContextMenu({ cardAndGames, currentCard, microSDeck } { showModal( { - microSDeck.updateCard(card); + Logger.Debug("Creating Card"); + await microSDeck.updateCard(card); await Promise.all(nonSteamAdditions.map(appId => { - const appName = collectionStore.deckDesktopApps?.apps.get(parseInt(appId))?.display_name ?? "Unknown Game"; + Logger.Debug(`Creating Non-Steam Game ${appId}`); + + const appName = collectionStore.deckDesktopApps?.allApps.find(v => v.appid == parseInt(appId))?.display_name ?? "Unknown Game"; return microSDeck.createGame({ uid: appId, name: appName, is_steam: false, size: 0 }) .catch(Error => Logger.Error("There was a critical error creating game: \"{Error}\"", { Error })); })); - - microSDeck.linkMany(card, nonSteamAdditions); - + + Logger.Debug("Created Non-Steam Games"); + + Logger.Debug("Linking Many"); + await microSDeck.linkMany(card, nonSteamAdditions); + + Logger.Debug("Unlinking Many"); await microSDeck.unlinkMany(card, nonSteamDeletions); }} card={{ ...card }} diff --git a/src/modals/EditCardModal.tsx b/src/modals/EditCardModal.tsx index 3b0f536..0c4c793 100644 --- a/src/modals/EditCardModal.tsx +++ b/src/modals/EditCardModal.tsx @@ -129,7 +129,7 @@ interface NonSteamPanelProps { const NonSteamPanel: VFC = ({ checkedIds, idsOnCard, numAdditions, numDeletions, style, onChange }) => { const [isOpen, setIsOpen] = useState(false); const [query, setQuery] = useState(""); - const idNamePairs: [number, string][] = useMemo(() => collectionStore.deckDesktopApps ? collectionStore.deckDesktopApps.allApps.map(appOverview => [appOverview.appid, appOverview.display_name]) : [], [collectionStore.deckDesktopApps?.allApps.length]); + const idNamePairs: [number, string][] = useMemo(() => collectionStore.deckDesktopApps ? collectionStore.deckDesktopApps.allApps.map(appOverview => [appOverview.appid, appOverview.display_name]) : [], [...(collectionStore.deckDesktopApps?.allApps.map(v => v.appid) ?? [])]); const [filteredPairs, setFilteredPairs] = useState(idNamePairs); useEffect(() => { From 3ffc23c99ec588d71490dce9618358fc6e532a53 Mon Sep 17 00:00:00 2001 From: CEbbinghaus Date: Sun, 22 Sep 2024 15:08:35 +1000 Subject: [PATCH 2/4] Added copy support for non deck users --- util/build.mjs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/util/build.mjs b/util/build.mjs index 193b159..f74016a 100644 --- a/util/build.mjs +++ b/util/build.mjs @@ -128,13 +128,15 @@ if (tasks.includes('collect')) { copyFileSync('package.json', 'build/package.json'); } -const is_local = existsSync('/home/deck/homebrew'); +const current_user = execSync("whoami").toString().trim(); + +const is_local = existsSync(`/home/${current_user}/homebrew`); if (is_local && tasks.includes('copy')) { Logger.Log('Copying build folder to local plugin directory'); - execSync(`sudo rm -rf /home/deck/homebrew/plugins/${PluginName}`); - execSync(`sudo cp -r build/ /home/deck/homebrew/plugins/${PluginName}`); - execSync(`sudo chmod 555 /home/deck/homebrew/plugins/${PluginName}`); + execSync(`sudo rm -rf /home/${current_user}/homebrew/plugins/${PluginName}`); + execSync(`sudo cp -r build/ /home/${current_user}/homebrew/plugins/${PluginName}`); + execSync(`sudo chmod 555 /home/${current_user}/homebrew/plugins/${PluginName}`); } else { if (!tasks.includes('copy')) { Logger.Log('Skipping copying build folder to local plugin directory'); From 96a4fb85fc816db0fbb4f535dbfee27eac2296ca Mon Sep 17 00:00:00 2001 From: CEbbinghaus Date: Sun, 22 Sep 2024 15:11:30 +1000 Subject: [PATCH 3/4] Updated Version --- backend/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/version b/backend/version index 933f18d..75955dd 100644 --- a/backend/version +++ b/backend/version @@ -1 +1 @@ -0.10.8 \ No newline at end of file +0.10.9 \ No newline at end of file From 859209407677b81102cfc0478080868b77266162 Mon Sep 17 00:00:00 2001 From: CEbbinghaus Date: Sun, 22 Sep 2024 15:28:47 +1000 Subject: [PATCH 4/4] Fixed build error --- backend/src/log.rs | 2 +- backend/src/steam.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/log.rs b/backend/src/log.rs index 1ccd6c6..50821b1 100644 --- a/backend/src/log.rs +++ b/backend/src/log.rs @@ -43,7 +43,7 @@ pub fn create_subscriber() { tracing_subscriber::fmt::layer() .pretty() .with_filter(tracing_subscriber::filter::LevelFilter::from_level( - log_level, + CONFIG.log_level, )) .with_filter(filter::filter_fn(|metadata| { metadata diff --git a/backend/src/steam.rs b/backend/src/steam.rs index 460ec71..d65a87b 100644 --- a/backend/src/steam.rs +++ b/backend/src/steam.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] use std::fmt::{Debug, Display}; use serde::Deserialize;