Add JSON manipulation action
This commit is contained in:
parent
1e916a644b
commit
83135b3045
13 changed files with 378 additions and 25 deletions
34
backend/Cargo.lock
generated
34
backend/Cargo.lock
generated
|
@ -97,6 +97,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"clap",
|
"clap",
|
||||||
|
"jmespath",
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -167,6 +168,12 @@ dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deunicode"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
@ -433,6 +440,24 @@ version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
|
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jmespath"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "017f8f53dd3b8ada762acb1f850da2a742d0ef3f921c60849a644380de1d683a"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"slug",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.126"
|
version = "0.2.126"
|
||||||
|
@ -805,6 +830,15 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slug"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373"
|
||||||
|
dependencies = [
|
||||||
|
"deunicode",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
|
|
|
@ -14,17 +14,18 @@ clap = { version = "3.2", features = ["derive", "std"], default-features = false
|
||||||
|
|
||||||
# async
|
# async
|
||||||
tokio = { version = "*", features = ["time"] }
|
tokio = { version = "*", features = ["time"] }
|
||||||
async-trait = "0.1.57"
|
async-trait = { version = "0.1.57" }
|
||||||
|
|
||||||
# json
|
# json
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = { version = "1.0" }
|
||||||
|
jmespath = { version = "0.3", features = [ "sync" ] }
|
||||||
|
|
||||||
regex = { version = "1" }
|
regex = { version = "1" }
|
||||||
|
|
||||||
# logging
|
# logging
|
||||||
log = "0.4"
|
log = { version = "0.4", features = ["max_level_debug", "release_max_level_warn"] }
|
||||||
simplelog = "0.12"
|
simplelog = { version = "0.12" }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = false
|
debug = false
|
||||||
|
|
|
@ -6,6 +6,7 @@ mod on_javascript_result;
|
||||||
mod on_update;
|
mod on_update;
|
||||||
mod reload;
|
mod reload;
|
||||||
mod run_js;
|
mod run_js;
|
||||||
|
mod steam_types;
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
pub use about::get_about;
|
pub use about::get_about;
|
||||||
|
@ -15,6 +16,7 @@ pub use on_javascript_result::on_javascript_result;
|
||||||
pub use on_update::on_update;
|
pub use on_update::on_update;
|
||||||
pub use reload::reload;
|
pub use reload::reload;
|
||||||
pub use run_js::{GetJavascriptEndpoint, JavascriptData};
|
pub use run_js::{GetJavascriptEndpoint, JavascriptData};
|
||||||
|
pub use steam_types::*;
|
||||||
pub(super) use types::*;
|
pub(super) use types::*;
|
||||||
|
|
||||||
pub(super) type ApiParameterType = Vec<usdpl_back::core::serdes::Primitive>;
|
pub(super) type ApiParameterType = Vec<usdpl_back::core::serdes::Primitive>;
|
||||||
|
|
198
backend/src/api/steam_types.rs
Normal file
198
backend/src/api/steam_types.rs
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
// list of these is second callback param for SteamClient.Downloads.RegisterForDownloadItems
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamDownloadInfo {
|
||||||
|
pub active: bool,
|
||||||
|
pub appid: usize,
|
||||||
|
pub buildid: usize,
|
||||||
|
pub target_buildid: usize,
|
||||||
|
pub paused: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
// only callback param for SteamClient.Downloads.RegisterForDownloadOverview
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamDownloadOverview {
|
||||||
|
pub paused: bool,
|
||||||
|
pub throttling_suspended: bool,
|
||||||
|
pub update_appid: usize,
|
||||||
|
pub update_bytes_downloaded: usize,
|
||||||
|
pub update_bytes_processed: usize,
|
||||||
|
pub update_bytes_staged: usize,
|
||||||
|
pub update_bytes_to_download: usize,
|
||||||
|
pub update_bytes_to_process: usize,
|
||||||
|
pub update_bytes_to_stage: usize,
|
||||||
|
pub update_disc_bytes_per_second: usize,
|
||||||
|
pub update_is_install: bool,
|
||||||
|
pub update_is_prefetch_estimate: bool,
|
||||||
|
pub update_is_shader: bool,
|
||||||
|
pub update_is_workshop: bool,
|
||||||
|
pub update_network_bytes_per_second: usize,
|
||||||
|
pub update_peak_network_bytes_per_second: usize,
|
||||||
|
pub update_seconds_remaining: isize, // -1 seems to indicate not-applicable
|
||||||
|
pub update_start_time: usize,
|
||||||
|
pub update_state: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// only param of callback for SteamClient.GameSessions.RegisterForAchievementNotification
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamAchievementNotification {
|
||||||
|
pub achievement: SteamAchievement,
|
||||||
|
pub nCurrentProgress: usize,
|
||||||
|
pub nMaxProgress: usize,
|
||||||
|
pub unAppID: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamAchievement {
|
||||||
|
pub bAchieved: bool,
|
||||||
|
pub bHidden: bool,
|
||||||
|
pub flAchieved: f64,
|
||||||
|
pub flCurrentProgress: f64,
|
||||||
|
pub flMaxProgress: f64,
|
||||||
|
pub flMinProgress: f64,
|
||||||
|
pub rtUnlocked: usize, // time since unix epoch
|
||||||
|
pub strDescription: String,
|
||||||
|
pub strID: String,
|
||||||
|
pub strImage: String,
|
||||||
|
pub strName: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// only param of callback for SteamClient.System.Bluetooth.RegisterForStateChanges
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamBluetoothState {
|
||||||
|
pub bEnabled: bool,
|
||||||
|
pub vecAdapters: Vec<SteamBluetoothAdapter>,
|
||||||
|
pub vecDevices: Vec<SteamBluetoothDevice>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamBluetoothDevice {
|
||||||
|
pub bConnected: bool,
|
||||||
|
pub bPaired: bool,
|
||||||
|
pub eType: usize, // enum, idk the options
|
||||||
|
pub nAdapterId: usize, // corresponds to SteamBluetoothAdapter.nId
|
||||||
|
pub nStrengthRaw: usize, // units???
|
||||||
|
pub sMAC: String,
|
||||||
|
pub sName: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamBluetoothAdapter {
|
||||||
|
pub bDiscovering: bool,
|
||||||
|
pub bEnabled: bool,
|
||||||
|
pub nId: usize,
|
||||||
|
pub sMAC: String,
|
||||||
|
pub sName: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// only param of callback for SteamClient.System.Network.RegisterForConnectivityTestChanges
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamConnectivityTestChange {
|
||||||
|
pub bChecking: bool,
|
||||||
|
pub eConnectivityTestResult: usize, // enum, idk the options
|
||||||
|
pub eFakeState: usize, // enum, idk the options
|
||||||
|
}
|
||||||
|
|
||||||
|
// only param of callback for SteamClient.System.Network.RegisterForNetworkDiagnostics
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamNetworkDiagnostic {
|
||||||
|
pub status: bool,
|
||||||
|
pub total_bytes: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
// only param of callback for SteamClient.System.Audio.RegisterForDeviceAdded
|
||||||
|
// and SteamClient.System.Audio.RegisterForDeviceAdded
|
||||||
|
// Also type of vecDevices of await SteamClient.System.Audio.GetDevices()
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamAudioDevice {
|
||||||
|
pub bHasInput: bool,
|
||||||
|
pub bHasOutput: bool,
|
||||||
|
pub bIsDefaultInputDevice: bool,
|
||||||
|
pub bIsDefaultOutputDevice: bool,
|
||||||
|
pub flInputVolume: f64,
|
||||||
|
pub flOutputVolume: f64,
|
||||||
|
pub id: usize,
|
||||||
|
pub sName: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// only param of callback for SteamClient.System.Display.RegisterForBrightnessChanges
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamBrightness {
|
||||||
|
pub flBrightness: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
// not a callback; await SteamClient.System.GetSystemInfo()
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamSystemInfo {
|
||||||
|
pub nCPUHz: usize,
|
||||||
|
pub nCPULogicalCores: usize,
|
||||||
|
pub nCPUPhysicalCores: usize,
|
||||||
|
pub nSteamVersion: usize,
|
||||||
|
pub nSystemRAMSizeMB: usize,
|
||||||
|
pub nVideoRAMSizeMB: usize,
|
||||||
|
pub sBIOSVersion: String,
|
||||||
|
pub sCPUName: String,
|
||||||
|
pub sCPUVendor: String,
|
||||||
|
pub sHostname: String,
|
||||||
|
pub sKernelVersion: String,
|
||||||
|
pub sOSBuildId: String,
|
||||||
|
pub sOSCodename: String,
|
||||||
|
pub sOSName: String,
|
||||||
|
pub sOSVariantId: String,
|
||||||
|
pub sOSVersionId: String,
|
||||||
|
pub sSteamAPI: String,
|
||||||
|
pub sSteamBuildDate: String,
|
||||||
|
pub sVideoCardName: String,
|
||||||
|
pub sVideoDriverVersion: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// only param of callback for SteamClient.System.RegisterForAirplaneModeChanges
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamAirplane {
|
||||||
|
pub bEnabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
// only param of callback for SteamClient.System.RegisterForBatteryStateChanges
|
||||||
|
// periodic
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamBattery {
|
||||||
|
pub bHasBattery: bool,
|
||||||
|
pub bShutdownRequested: bool,
|
||||||
|
pub eACState: usize,
|
||||||
|
pub eBatteryState: usize,
|
||||||
|
pub flLevel: f64,
|
||||||
|
pub nSecondsRemaining: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
// only param of callback for SteamClient.GameSessions.RegisterForScreenshotNotification
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamScreenshotNotification {
|
||||||
|
pub details: SteamScreenshot,
|
||||||
|
pub hScreenshot: usize,
|
||||||
|
pub strOperation: String,
|
||||||
|
pub unAppID: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamScreenshot {
|
||||||
|
pub bSpoilers: bool,
|
||||||
|
pub bUploaded: bool,
|
||||||
|
pub ePrivacy: usize, // enum
|
||||||
|
pub hHandle: usize,
|
||||||
|
pub nAppID: usize,
|
||||||
|
pub nCreated: usize,
|
||||||
|
pub nHeight: usize,
|
||||||
|
pub nWidth: usize,
|
||||||
|
pub strCaption: String,
|
||||||
|
pub strUrl: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// list of these is only param of callback for SteamClient.Input.RegisterForControllerInputMessages
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SteamControllerInputMessage {
|
||||||
|
pub bState: bool,
|
||||||
|
pub nController: usize,
|
||||||
|
pub strActionName: String,
|
||||||
|
}
|
|
@ -109,3 +109,26 @@ impl ApiJavascriptResult {
|
||||||
Self::Error(ApiError::new(msg, err))
|
Self::Error(ApiError::new(msg, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
#[serde(tag = "event")]
|
||||||
|
pub enum ApiRegisteredEvent {
|
||||||
|
#[serde(rename = "resume-from-suspend")]
|
||||||
|
ResumeFromSuspend,
|
||||||
|
#[serde(rename = "suspend-from-awake")]
|
||||||
|
SuspendRequest,
|
||||||
|
#[serde(rename = "download-items")]
|
||||||
|
DownloadList(ApiDownloadList),
|
||||||
|
#[serde(rename = "download-overview")]
|
||||||
|
DownloadOverview(super::SteamDownloadOverview),
|
||||||
|
#[serde(rename = "achievement-notification")]
|
||||||
|
AchievementNotification(super::SteamAchievementNotification),
|
||||||
|
#[serde(rename = "error")]
|
||||||
|
Error(ApiError),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct ApiDownloadList {
|
||||||
|
pub is_paused: bool,
|
||||||
|
pub list: Vec<super::SteamDownloadInfo>,
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ pub enum TopLevelActionConfig {
|
||||||
Mirror(MirrorAction),
|
Mirror(MirrorAction),
|
||||||
#[serde(rename = "javascript")]
|
#[serde(rename = "javascript")]
|
||||||
Javascript(JavascriptAction),
|
Javascript(JavascriptAction),
|
||||||
|
#[serde(rename = "json")]
|
||||||
|
Json(JsonAction),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
@ -24,6 +26,8 @@ pub enum ActionConfig {
|
||||||
Transform(super::TransformAction),
|
Transform(super::TransformAction),
|
||||||
#[serde(rename = "javascript")]
|
#[serde(rename = "javascript")]
|
||||||
Javascript(JavascriptAction),
|
Javascript(JavascriptAction),
|
||||||
|
#[serde(rename = "json")]
|
||||||
|
Json(JsonAction),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
@ -43,3 +47,8 @@ pub struct MirrorAction;
|
||||||
pub struct JavascriptAction {
|
pub struct JavascriptAction {
|
||||||
pub run: String,
|
pub run: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct JsonAction {
|
||||||
|
pub jmespath: String,
|
||||||
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ mod toggle;
|
||||||
mod transformer;
|
mod transformer;
|
||||||
|
|
||||||
pub use about::AboutConfig;
|
pub use about::AboutConfig;
|
||||||
pub use action::{TopLevelActionConfig, ActionConfig, CommandAction, MirrorAction, SequenceAction, JavascriptAction};
|
pub use action::{TopLevelActionConfig, ActionConfig, CommandAction, MirrorAction, SequenceAction, JavascriptAction, JsonAction};
|
||||||
pub use base::BaseConfig;
|
pub use base::BaseConfig;
|
||||||
pub use button::ButtonConfig;
|
pub use button::ButtonConfig;
|
||||||
pub use element::ElementConfig;
|
pub use element::ElementConfig;
|
||||||
|
|
|
@ -13,8 +13,7 @@ fn main() -> Result<(), ()> {
|
||||||
let cli_args = cli::CliArgs::cli();
|
let cli_args = cli::CliArgs::cli();
|
||||||
let log_filepath = cli_args.log.unwrap_or_else(|| format!("/tmp/{}.log", consts::PACKAGE_NAME).into());
|
let log_filepath = cli_args.log.unwrap_or_else(|| format!("/tmp/{}.log", consts::PACKAGE_NAME).into());
|
||||||
WriteLogger::init(
|
WriteLogger::init(
|
||||||
#[cfg(debug_assertions)]{LevelFilter::Debug},
|
LevelFilter::Off,
|
||||||
#[cfg(not(debug_assertions))]{LevelFilter::Info},
|
|
||||||
Default::default(),
|
Default::default(),
|
||||||
std::fs::File::create(&log_filepath).expect(&format!("Failed create log file {}", log_filepath.display()))
|
std::fs::File::create(&log_filepath).expect(&format!("Failed create log file {}", log_filepath.display()))
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
|
@ -52,6 +52,7 @@ pub enum TopLevelActorType {
|
||||||
Mirror,
|
Mirror,
|
||||||
Sequence(super::SequenceActor),
|
Sequence(super::SequenceActor),
|
||||||
Javascript(super::JavascriptActor),
|
Javascript(super::JavascriptActor),
|
||||||
|
Json(super::JsonActor),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> SeqAct<'a> for TopLevelActorType {
|
impl<'a> SeqAct<'a> for TopLevelActorType {
|
||||||
|
@ -69,7 +70,9 @@ impl<'a> SeqAct<'a> for TopLevelActorType {
|
||||||
TopLevelActionConfig::Mirror(_) =>
|
TopLevelActionConfig::Mirror(_) =>
|
||||||
Self::Mirror,
|
Self::Mirror,
|
||||||
TopLevelActionConfig::Javascript(j) =>
|
TopLevelActionConfig::Javascript(j) =>
|
||||||
Self::Javascript(super::JavascriptActor::build(j, parameter)?)
|
Self::Javascript(super::JavascriptActor::build(j, parameter)?),
|
||||||
|
TopLevelActionConfig::Json(j) =>
|
||||||
|
Self::Json(super::JsonActor::build(j, ())?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +83,7 @@ impl<'a> SeqAct<'a> for TopLevelActorType {
|
||||||
Self::Mirror => p,
|
Self::Mirror => p,
|
||||||
Self::Sequence(s) => s.run(p),
|
Self::Sequence(s) => s.run(p),
|
||||||
Self::Javascript(j) => j.run(p),
|
Self::Javascript(j) => j.run(p),
|
||||||
|
Self::Json(j) => j.run(p),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,6 +92,7 @@ pub enum ActorType {
|
||||||
Command(super::CommandActor),
|
Command(super::CommandActor),
|
||||||
Transform(super::TransformActor),
|
Transform(super::TransformActor),
|
||||||
Javascript(super::JavascriptActor),
|
Javascript(super::JavascriptActor),
|
||||||
|
Json(super::JsonActor),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> SeqAct<'a> for ActorType {
|
impl<'a> SeqAct<'a> for ActorType {
|
||||||
|
@ -101,7 +106,9 @@ impl<'a> SeqAct<'a> for ActorType {
|
||||||
ActionConfig::Transform(t) =>
|
ActionConfig::Transform(t) =>
|
||||||
Self::Transform(super::TransformActor::build(t, ())?),
|
Self::Transform(super::TransformActor::build(t, ())?),
|
||||||
ActionConfig::Javascript(j) =>
|
ActionConfig::Javascript(j) =>
|
||||||
Self::Javascript(super::JavascriptActor::build(j, parameter)?)
|
Self::Javascript(super::JavascriptActor::build(j, parameter)?),
|
||||||
|
ActionConfig::Json(j) =>
|
||||||
|
Self::Json(super::JsonActor::build(j, ())?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +117,7 @@ impl<'a> SeqAct<'a> for ActorType {
|
||||||
Self::Command(c) => c.run(p),
|
Self::Command(c) => c.run(p),
|
||||||
Self::Transform(t) => t.run(p),
|
Self::Transform(t) => t.run(p),
|
||||||
Self::Javascript(j) => j.run(p),
|
Self::Javascript(j) => j.run(p),
|
||||||
|
Self::Json(j) => j.run(p),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
77
backend/src/runtime/actors/json_actor.rs
Normal file
77
backend/src/runtime/actors/json_actor.rs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
use usdpl_back::core::serdes::Primitive;
|
||||||
|
|
||||||
|
use jmespath::{Expression, Variable};
|
||||||
|
|
||||||
|
use crate::config::JsonAction;
|
||||||
|
use super::{SeqAct, ActError};
|
||||||
|
|
||||||
|
pub struct JsonActor {
|
||||||
|
expr: Expression<'static>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl JsonActor {
|
||||||
|
fn jmespath_value_to_primitive(var: Variable) -> Primitive {
|
||||||
|
match var {
|
||||||
|
Variable::Null => Primitive::Empty,
|
||||||
|
Variable::String(s) => Primitive::String(s),
|
||||||
|
Variable::Bool(b) => Primitive::Bool(b),
|
||||||
|
Variable::Number(f) => f.as_f64().map(|x| Primitive::F64(x)).unwrap_or(Primitive::Empty),
|
||||||
|
Variable::Array(arr) => serde_json::to_string(&arr)
|
||||||
|
.map(Primitive::Json)
|
||||||
|
.unwrap_or(Primitive::Empty),
|
||||||
|
Variable::Object(obj) => serde_json::to_string(&obj)
|
||||||
|
.map(Primitive::Json)
|
||||||
|
.unwrap_or(Primitive::Empty),
|
||||||
|
Variable::Expref(_) => {
|
||||||
|
log::warn!("The jmespath result cannot be another jmespath");
|
||||||
|
Primitive::Empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> SeqAct<'a> for JsonActor {
|
||||||
|
type BuildParam = ();
|
||||||
|
type Config = JsonAction;
|
||||||
|
|
||||||
|
fn build(config: &'a Self::Config, _: Self::BuildParam) -> Result<Self, ActError> {
|
||||||
|
Ok(
|
||||||
|
Self {
|
||||||
|
expr: jmespath::compile(&config.jmespath)
|
||||||
|
.map_err(|e| format!("Failed to compile jmespath `{}`: {}", config.jmespath, e))?,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(self, parameter: Primitive) -> Primitive {
|
||||||
|
match parameter {
|
||||||
|
Primitive::Json(json) => {
|
||||||
|
match Variable::from_json(&json) {
|
||||||
|
Ok(var) => {
|
||||||
|
match self.expr.search(var) {
|
||||||
|
Ok(result) => Self::jmespath_value_to_primitive(
|
||||||
|
std::sync::Arc::try_unwrap(result)
|
||||||
|
.unwrap_or_else(|e| {
|
||||||
|
log::debug!("Cloning jmespath search result");
|
||||||
|
(*e).clone()
|
||||||
|
})
|
||||||
|
),
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Cannot search through JSON `{}`: {}", json, e);
|
||||||
|
Primitive::Empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Cannot convert to jmespath Variable from JSON `{}`: {}", json, e);
|
||||||
|
Primitive::Empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
log::error!("Cannot apply JSON action to non-JSON primitive");
|
||||||
|
Primitive::Empty
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
mod actor;
|
mod actor;
|
||||||
mod command_actor;
|
mod command_actor;
|
||||||
mod javascript_actor;
|
mod javascript_actor;
|
||||||
|
mod json_actor;
|
||||||
mod periodic_actor;
|
mod periodic_actor;
|
||||||
mod sequential_actor;
|
mod sequential_actor;
|
||||||
mod transform_actor;
|
mod transform_actor;
|
||||||
|
@ -8,6 +9,7 @@ mod transform_actor;
|
||||||
pub use actor::{Actor, Act, ActError, ActorType, SeqAct, SeqActor, TopLevelActorType};
|
pub use actor::{Actor, Act, ActError, ActorType, SeqAct, SeqActor, TopLevelActorType};
|
||||||
pub use command_actor::CommandActor;
|
pub use command_actor::CommandActor;
|
||||||
pub use javascript_actor::JavascriptActor;
|
pub use javascript_actor::JavascriptActor;
|
||||||
|
pub use json_actor::JsonActor;
|
||||||
pub use periodic_actor::PeriodicActor;
|
pub use periodic_actor::PeriodicActor;
|
||||||
pub use sequential_actor::SequenceActor;
|
pub use sequential_actor::SequenceActor;
|
||||||
pub use transform_actor::TransformActor;
|
pub use transform_actor::TransformActor;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "caylon",
|
"name": "caylon",
|
||||||
"version": "0.0.1",
|
"version": "0.1.0",
|
||||||
"description": "Better than the Borg",
|
"description": "Better than the Borg",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "shx rm -rf dist && rollup -c",
|
"build": "shx rm -rf dist && rollup -c",
|
||||||
|
|
|
@ -40,19 +40,19 @@ function displayCallback(index: number) {
|
||||||
switch (newVal.result) {
|
switch (newVal.result) {
|
||||||
case "value":
|
case "value":
|
||||||
let val = newVal as backend.CValueResult;
|
let val = newVal as backend.CValueResult;
|
||||||
console.log("KAYLON: Got display for " + index.toString(), val);
|
console.log("CAYLON: Got display for " + index.toString(), val);
|
||||||
set_value(DISPLAY_KEY + index.toString(), val.value);
|
set_value(DISPLAY_KEY + index.toString(), val.value);
|
||||||
break;
|
break;
|
||||||
case "error":
|
case "error":
|
||||||
let err = newVal as backend.CErrorResult;
|
let err = newVal as backend.CErrorResult;
|
||||||
console.warn("KAYLON: Got display error for " + index.toString(), err);
|
console.warn("CAYLON: Got display error for " + index.toString(), err);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.error("KAYLON: Got invalid display response for " + index.toString(), newVal);
|
console.error("CAYLON: Got invalid display response for " + index.toString(), newVal);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn("KAYLON: Ignoring null display result for " + index.toString());
|
console.warn("CAYLON: Ignoring null display result for " + index.toString());
|
||||||
}
|
}
|
||||||
updateTasks.push(() => backend.resolve(backend.getDisplay(index), displayCallback(index)));
|
updateTasks.push(() => backend.resolve(backend.getDisplay(index), displayCallback(index)));
|
||||||
update();
|
update();
|
||||||
|
@ -61,7 +61,7 @@ function displayCallback(index: number) {
|
||||||
|
|
||||||
function onGetElements() {
|
function onGetElements() {
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
console.log("KAYLON: req display for item #" + i.toString());
|
console.log("CAYLON: req display for item #" + i.toString());
|
||||||
backend.resolve(backend.getDisplay(i), displayCallback(i));
|
backend.resolve(backend.getDisplay(i), displayCallback(i));
|
||||||
}
|
}
|
||||||
backend.resolve(backend.getJavascriptToRun(), jsCallback());
|
backend.resolve(backend.getJavascriptToRun(), jsCallback());
|
||||||
|
@ -77,16 +77,16 @@ function jsCallback() {
|
||||||
switch (script.result) {
|
switch (script.result) {
|
||||||
case "javascript":
|
case "javascript":
|
||||||
let toRun = script as backend.CJavascriptResult;
|
let toRun = script as backend.CJavascriptResult;
|
||||||
console.log("KAYLON: Got javascript " + toRun.id.toString(), toRun);
|
console.log("CAYLON: Got javascript " + toRun.id.toString(), toRun);
|
||||||
let result = eval2(toRun.raw);
|
let result = eval2(toRun.raw);
|
||||||
backend.onJavascriptResult(toRun.id, result);
|
backend.onJavascriptResult(toRun.id, result);
|
||||||
break;
|
break;
|
||||||
case "error":
|
case "error":
|
||||||
let err = script as backend.CErrorResult;
|
let err = script as backend.CErrorResult;
|
||||||
console.warn("KAYLON: Got javascript retrieval error", err);
|
console.warn("CAYLON: Got javascript retrieval error", err);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.error("KAYLON: Got invalid javascript response", script);
|
console.error("CAYLON: Got invalid javascript response", script);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,14 +100,14 @@ function jsCallback() {
|
||||||
let about_promise = backend.getAbout();
|
let about_promise = backend.getAbout();
|
||||||
let elements_promise = backend.getElements();
|
let elements_promise = backend.getElements();
|
||||||
about = await about_promise;
|
about = await about_promise;
|
||||||
console.log("KAYLON: got about", about);
|
console.log("CAYLON: got about", about);
|
||||||
let result = await elements_promise;
|
let result = await elements_promise;
|
||||||
console.log("KAYLON: got elements", result);
|
console.log("CAYLON: got elements", result);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
items = result;
|
items = result;
|
||||||
onGetElements();
|
onGetElements();
|
||||||
} else {
|
} else {
|
||||||
console.warn("KAYLON: backend connection failed");
|
console.warn("CAYLON: backend connection failed");
|
||||||
}
|
}
|
||||||
backend.resolve(backend.getJavascriptToRun(), jsCallback());
|
backend.resolve(backend.getJavascriptToRun(), jsCallback());
|
||||||
})();
|
})();
|
||||||
|
@ -146,19 +146,19 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
|
||||||
backend.resolve(backend.reload(),
|
backend.resolve(backend.reload(),
|
||||||
(reload_items: backend.CElement[]) => {
|
(reload_items: backend.CElement[]) => {
|
||||||
items = reload_items;
|
items = reload_items;
|
||||||
console.log("KAYLON: got elements", reload_items);
|
console.log("CAYLON: got elements", reload_items);
|
||||||
if (reload_items != null) {
|
if (reload_items != null) {
|
||||||
items = reload_items;
|
items = reload_items;
|
||||||
onGetElements();
|
onGetElements();
|
||||||
} else {
|
} else {
|
||||||
console.warn("KAYLON: backend connection failed");
|
console.warn("CAYLON: backend connection failed");
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
backend.resolve(backend.getAbout(),
|
backend.resolve(backend.getAbout(),
|
||||||
(new_about: backend.CAbout) => {
|
(new_about: backend.CAbout) => {
|
||||||
about = new_about;
|
about = new_about;
|
||||||
console.log("KAYLON: got about", about);
|
console.log("CAYLON: got about", about);
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
|
@ -182,7 +182,7 @@ function buildHtmlElement(element: backend.CElement, index: number, updateIdc: a
|
||||||
case "result-display":
|
case "result-display":
|
||||||
return buildResultDisplay(element as backend.CResultDisplay, index, updateIdc);
|
return buildResultDisplay(element as backend.CResultDisplay, index, updateIdc);
|
||||||
}
|
}
|
||||||
console.error("KAYLON: Unsupported element", element);
|
console.error("CAYLON: Unsupported element", element);
|
||||||
return <div>Unsupported</div>;
|
return <div>Unsupported</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue