Profile: 33917193...

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

{"id":"d685d2683288d3247933e2de0f42f6dc273dd410","tree":"4302487b1f8c4b6048436b70bdcd2a857412aeb5","parents":["34b0e967cfa04f4b42079985ad3f3511e0ac51ef"],"author_name":"randymcmillan","author_email":"randymcmillan@protonmail.com","committer_name":"randymcmillan","committer_email":"randymcmillan@protonmail.com","message":"src/lib/sub_commands/chat.rs:intermediate\n\ndiff --git a/src/lib/cli.rs b/src/lib/cli.rs\nindex c253d97c..a32c01fb 100644\n--- a/src/lib/cli.rs\n+++ b/src/lib/cli.rs\n@@ -44,12 +44,12 @@ pub enum Commands {\n Login(sub_commands::login::SubCommandArgs),\n }\n\n-#[derive(Parser)]\n+#[derive(Parser, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatCli {\n- #[command(subcommand)]\n- pub command: ChatCommands,\n+ // #[command(subcommand)]\n+ // pub command: ChatCommands,\n /// remote signer address\n //#[arg(long, global = true)]\n //pub bunker_uri: Option,\n@@ -67,22 +67,22 @@ pub struct ChatCli {\n //pub disable_cli_spinners: bool,\n }\n\n-#[derive(Subcommand)]\n-pub enum ChatCommands {\n- /// update cache with latest updates from nostr\n- Fetch(sub_commands::fetch::SubCommandArgs),\n- /// signal you are this repo's maintainer accepting proposals via\n- /// nostr\n- Init(sub_commands::init::SubCommandArgs),\n- /// issue commits as a proposal\n- Send(sub_commands::send::SubCommandArgs),\n- /// list proposals; checkout, apply or download selected\n- List,\n- /// send proposal revision\n- Push(sub_commands::push::SubCommandArgs),\n- /// fetch and apply new proposal commits / revisions linked to\n- /// branch\n- Pull,\n- /// run with --nsec flag to change npub\n- Login(sub_commands::login::SubCommandArgs),\n-}\n+//#[derive(Subcommand, Debug)]\n+//pub enum ChatCommands {\n+// /// update cache with latest updates from nostr\n+// Fetch(sub_commands::fetch::SubCommandArgs),\n+// /// signal you are this repo's maintainer accepting proposals via\n+// /// nostr\n+// Init(sub_commands::init::SubCommandArgs),\n+// /// issue commits as a proposal\n+// Send(sub_commands::send::SubCommandArgs),\n+// /// list proposals; checkout, apply or download selected\n+// List,\n+// /// send proposal revision\n+// Push(sub_commands::push::SubCommandArgs),\n+// /// fetch and apply new proposal commits / revisions linked to\n+// /// branch\n+// Pull,\n+// /// run with --nsec flag to change npub\n+// Login(sub_commands::login::SubCommandArgs),\n+//}\ndiff --git a/src/lib/sub_commands/chat.rs b/src/lib/sub_commands/chat.rs\nindex 68edc3d3..bec002f5 100644\n--- a/src/lib/sub_commands/chat.rs\n+++ b/src/lib/sub_commands/chat.rs\n@@ -1,6 +1,6 @@\n #![cfg_attr(not(test), warn(clippy::pedantic))]\n #![cfg_attr(not(test), warn(clippy::expect_used))]\n-use crate::cli::ChatCommands;\n+//use crate::cli::ChatCommands;\n use crate::sub_commands::fetch;\n use crate::sub_commands::init;\n use crate::sub_commands::list;\n@@ -44,12 +44,12 @@ use tracing::{debug, info, Level};\n use tracing_subscriber::util::SubscriberInitExt;\n use tracing_subscriber::{fmt, layer::SubscriberExt, EnvFilter, Registry};\n\n-#[derive(Args)]\n+#[derive(Args, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatSubCommand {\n- #[command(subcommand)]\n- command: ChatCommands,\n+ //#[command(subcommand)]\n+ //command: ChatCommands,\n ///// nsec or hex private key\n #[arg(short, long, global = true)]\n nsec: Option,\n@@ -73,366 +73,367 @@ pub struct ChatSubCommand {\n }\n\n pub async fn chat(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- match &sub_command_args.command {\n- ChatCommands::Login(args) => login::launch(&args).await?,\n- ChatCommands::Init(args) => init::launch(&args).await?,\n- ChatCommands::Send(args) => send::launch(&args, true).await?,\n- ChatCommands::List => list::launch().await?,\n- ChatCommands::Pull => pull::launch().await?,\n- ChatCommands::Push(args) => push::launch(&args).await?,\n- ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n-\t\t_ => return Ok(()),\n-\t}\n- //continue\n-\n- run(sub_command_args);\n+ //match &sub_command_args.command {\n+ //// ChatCommands::Login(args) => login::launch(&args).await?,\n+ //// ChatCommands::Init(args) => init::launch(&args).await?,\n+ //// ChatCommands::Send(args) => send::launch(&args, true).await?,\n+ //// ChatCommands::List => list::launch().await?,\n+ //// ChatCommands::Pull => pull::launch().await?,\n+ //// ChatCommands::Push(args) => push::launch(&args).await?,\n+ //// ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n+ //\t_ => { run(sub_command_args).await? }\n+ //}\n+ run(sub_command_args).await?;\n\n Ok(())\n }\n\n pub async fn run(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- let args = sub_command_args;\n-\n- if let Some(name) = args.name.clone() {\n- use std::env;\n- env::set_var(\"USER\", &name);\n- };\n-\n- let level = if args.debug {\n- Level::DEBUG\n- } else if args.trace {\n- Level::TRACE\n- } else if args.info {\n- Level::INFO\n- } else {\n- Level::WARN\n- };\n-\n- let filter = EnvFilter::default()\n- .add_directive(level.into())\n- .add_directive(\"nostr_sdk=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n- .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n- .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n- .add_directive(\"gnostr::message=off\".parse().unwrap())\n- .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n- .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n- //\n- .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n-\n- let subscriber = Registry::default()\n- .with(fmt::layer().with_writer(std::io::stdout))\n- .with(filter);\n-\n- let _ = subscriber.try_init();\n-\n- if args.debug || args.trace {\n- if args.nsec.clone().is_some() {\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n- print!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- print!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n- }\n- }\n- //parse keys from sha256 hash\n- let empty_hash_keys =\n- Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n-\n- if args.nsec.is_some() {\n- //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n-\n- info!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n-\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\")?;\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head()?;\n- let obj = head.resolve()?.peel(ObjectType::Commit)?;\n-\n- //read top commit\n- let commit = obj.peel_to_commit()?;\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"416:commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id);\n- info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n-\n- //// commit based keys\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n- custom_tags.insert(\n- padded_keys.clone().public_key().to_string(),\n- vec![\"GNOSTR\".to_string()],\n- );\n-\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n- info!(\"467:signed_event:\\n{:?}\", signed_event);\n- });\n-\n- //TODO config metadata\n-\n- //access some git info\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- let binding = serialized_commit.clone();\n- let deserialized_commit = deserialize_commit(&repo, &binding)?;\n- info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n-\n- //access commit summary in the deserialized commit\n- info!(\"481:Original commit ID:\\n{}\", commit_id);\n- info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n-\n- //additional checking\n- if commit.id() != deserialized_commit.id() {\n- debug!(\"Commit IDs do not match!\");\n- } else {\n- debug!(\"Commit IDs match!\");\n- }\n-\n- let value: Value = parse_json(&serialized_commit)?;\n- //info!(\"value:\\n{}\", value);\n-\n- // Accessing object elements.\n- if let Some(id) = value.get(\"id\") {\n- info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n- }\n- if let Some(tree) = value.get(\"tree\") {\n- info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n- }\n- // Accessing parent commits (merge may be array)\n- if let Some(parent) = value.get(\"parents\") {\n- if let Value::Array(arr) = parent {\n- if let Some(parent) = arr.get(0) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n- }\n- if let Some(parent) = arr.get(1) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n- }\n- }\n- }\n- if let Some(author_name) = value.get(\"author_name\") {\n- info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(author_email) = value.get(\"author_email\") {\n- info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_name) = value.get(\"committer_name\") {\n- info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_email) = value.get(\"committer_email\") {\n- info!(\n- \"committer_email:\\n{}\",\n- committer_email.as_str().unwrap_or(\"\")\n- );\n- }\n-\n- //split the commit message into a Vec\n- if let Some(message) = value.get(\"message\") {\n- let parts = split_json_string(&message, \"\\n\");\n- for part in parts {\n- info!(\"\\n{}\", part);\n- }\n- debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n- }\n- if let Value::Number(time) = &value[\"time\"] {\n- info!(\"time:\\n{}\", time);\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\").expect(\"\");\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head().expect(\"\");\n- let obj = head\n- .resolve()\n- .expect(\"\")\n- .peel(ObjectType::Commit)\n- .expect(\"\");\n-\n- //read top commit\n- let commit = obj.peel_to_commit().expect(\"\");\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n- //// commit based keys\n- //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n- //create nostr client with commit based keys\n- //let client = Client::new(keys);\n- let client = Client::new(padded_keys.clone());\n- global_rt().spawn(async move {\n- client\n- .add_relay(\"wss://relay.damus.io\")\n- .await\n- .expect(\"failed to add damus relay\");\n- client\n- .add_relay(\"wss://nos.lol\")\n- .await\n- .expect(\"failed to add nos.lol relay\");\n- client.connect().await; // connect() likely doesn't return a Result you can match on\n- let builder = EventBuilder::text_note(serialized_commit.clone());\n- let output = client\n- .send_event_builder(builder)\n- .await\n- .expect(\"589:failed to send event\");\n- info!(\"Event ID: {}\", output.id());\n- info!(\n- \"Event ID BECH32: {}\",\n- output\n- .id()\n- //.public_key()\n- .to_bech32()\n- .expect(\"failed to convert to bech32\")\n- );\n- info!(\"Sent to: {:?}\", output.success);\n- info!(\"Not sent to: {:?}\", output.failed);\n- });\n-\n- //std::process::exit(0);\n-\n- //P2P CHAT\n- let mut app = ui::App::default();\n-\n- //TODO\n- //for line in TITLE.lines() {\n+ println!(\"{:?}\", &sub_command_args);\n+ let chat = chat;\n+\n+ // let args = sub_command_args;\n+ //\n+ // if let Some(name) = args.name.clone() {\n+ // use std::env;\n+ // env::set_var(\"USER\", &name);\n+ // };\n+ //\n+ // let level = if args.debug {\n+ // Level::DEBUG\n+ // } else if args.trace {\n+ // Level::TRACE\n+ // } else if args.info {\n+ // Level::INFO\n+ // } else {\n+ // Level::WARN\n+ // };\n+ //\n+ // let filter = EnvFilter::default()\n+ // .add_directive(level.into())\n+ // .add_directive(\"nostr_sdk=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n+ // .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::message=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n+ // .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n+ // //\n+ // .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n+ //\n+ // let subscriber = Registry::default()\n+ // .with(fmt::layer().with_writer(std::io::stdout))\n+ // .with(filter);\n+ //\n+ // let _ = subscriber.try_init();\n+ //\n+ // if args.debug || args.trace {\n+ // if args.nsec.clone().is_some() {\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ // debug!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // debug!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ // }\n+ // }\n+ // //parse keys from sha256 hash\n+ // let empty_hash_keys =\n+ // Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // if args.nsec.is_some() {\n+ // //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ //\n+ // info!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ //\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\")?;\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head()?;\n+ // let obj = head.resolve()?.peel(ObjectType::Commit)?;\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit()?;\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"416:commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id);\n+ // info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n+ //\n+ // //// commit based keys\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ // custom_tags.insert(\n+ // padded_keys.clone().public_key().to_string(),\n+ // vec![\"GNOSTR\".to_string()],\n+ // );\n+ //\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n+ // info!(\"467:signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // //TODO config metadata\n+ //\n+ // //access some git info\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // let binding = serialized_commit.clone();\n+ // let deserialized_commit = deserialize_commit(&repo, &binding)?;\n+ // info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n+ //\n+ // //access commit summary in the deserialized commit\n+ // info!(\"481:Original commit ID:\\n{}\", commit_id);\n+ // info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n+ //\n+ // //additional checking\n+ // if commit.id() != deserialized_commit.id() {\n+ // debug!(\"Commit IDs do not match!\");\n+ // } else {\n+ // debug!(\"Commit IDs match!\");\n+ // }\n+ //\n+ // let value: Value = parse_json(&serialized_commit)?;\n+ // //info!(\"value:\\n{}\", value);\n+ //\n+ // // Accessing object elements.\n+ // if let Some(id) = value.get(\"id\") {\n+ // info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(tree) = value.get(\"tree\") {\n+ // info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n+ // }\n+ // // Accessing parent commits (merge may be array)\n+ // if let Some(parent) = value.get(\"parents\") {\n+ // if let Value::Array(arr) = parent {\n+ // if let Some(parent) = arr.get(0) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n+ // }\n+ // if let Some(parent) = arr.get(1) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n+ // }\n+ // }\n+ // }\n+ // if let Some(author_name) = value.get(\"author_name\") {\n+ // info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(author_email) = value.get(\"author_email\") {\n+ // info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_name) = value.get(\"committer_name\") {\n+ // info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_email) = value.get(\"committer_email\") {\n+ // info!(\n+ // \"committer_email:\\n{}\",\n+ // committer_email.as_str().unwrap_or(\"\")\n+ // );\n+ // }\n+ //\n+ // //split the commit message into a Vec\n+ // if let Some(message) = value.get(\"message\") {\n+ // let parts = split_json_string(&message, \"\\n\");\n+ // for part in parts {\n+ // info!(\"\\n{}\", part);\n+ // }\n+ // debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Value::Number(time) = &value[\"time\"] {\n+ // info!(\"time:\\n{}\", time);\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\").expect(\"\");\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head().expect(\"\");\n+ // let obj = head\n+ // .resolve()\n+ // .expect(\"\")\n+ // .peel(ObjectType::Commit)\n+ // .expect(\"\");\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit().expect(\"\");\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n+ // //// commit based keys\n+ // //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ // //create nostr client with commit based keys\n+ // //let client = Client::new(keys);\n+ // let client = Client::new(padded_keys.clone());\n+ // global_rt().spawn(async move {\n+ // client\n+ // .add_relay(\"wss://relay.damus.io\")\n+ // .await\n+ // .expect(\"failed to add damus relay\");\n+ // client\n+ // .add_relay(\"wss://nos.lol\")\n+ // .await\n+ // .expect(\"failed to add nos.lol relay\");\n+ // client.connect().await; // connect() likely doesn't return a Result you can match on\n+ // let builder = EventBuilder::text_note(serialized_commit.clone());\n+ // let output = client\n+ // .send_event_builder(builder)\n+ // .await\n+ // .expect(\"589:failed to send event\");\n+ // info!(\"Event ID: {}\", output.id());\n+ // info!(\n+ // \"Event ID BECH32: {}\",\n+ // output\n+ // .id()\n+ // //.public_key()\n+ // .to_bech32()\n+ // .expect(\"failed to convert to bech32\")\n+ // );\n+ // info!(\"Sent to: {:?}\", output.success);\n+ // info!(\"Not sent to: {:?}\", output.failed);\n+ // });\n+ //\n+ // //std::process::exit(0);\n+ //\n+ // //P2P CHAT\n+ // let mut app = ui::App::default();\n+ //\n+ // //TODO\n+ // //for line in TITLE.lines() {\n+ // // app.add_message(\n+ // // Msg::default()\n+ // // .set_content(line.to_string())\n+ // // .set_kind(MsgKind::Raw),\n+ // // );\n+ // //}\n+ //\n+ // use crate::chat::generate_nostr_keys_from_commit_hash;\n+ // let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // info!(\"keys.public_key():\\n{}\", keys.public_key());\n // app.add_message(\n // Msg::default()\n- // .set_content(line.to_string())\n+ // .set_content(keys.public_key().to_string())\n // .set_kind(MsgKind::Raw),\n // );\n- //}\n-\n- use crate::chat::generate_nostr_keys_from_commit_hash;\n- let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- info!(\"keys.public_key():\\n{}\", keys.public_key());\n- app.add_message(\n- Msg::default()\n- .set_content(keys.public_key().to_string())\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"second message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"third message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"fourth message\"))\n- .set_kind(MsgKind::Raw),\n- );\n-\n- let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n- let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n-\n- // let input_loop_fut = input_loop(input_tx);\n- let input_tx_clone = input_tx.clone();\n- app.on_submit(move |m| {\n- debug!(\"sent: {:?}\", m);\n- input_tx_clone.blocking_send(m).unwrap();\n- });\n-\n- let topic = if args.topic.is_some() {\n- args.topic.clone()\n- } else {\n- Some(String::from(commit_id.to_string()))\n- };\n-\n- app.topic = topic.clone().unwrap();\n-\n- let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n-\n- global_rt().spawn(async move {\n- evt_loop(input_rx, peer_tx, topic).await.unwrap();\n- });\n-\n- // recv from peer\n- let mut tui_msg_adder = app.add_msg_fn();\n- global_rt().spawn(async move {\n- while let Some(m) = peer_rx.recv().await {\n- debug!(\"recv: {:?}\", m);\n- tui_msg_adder(m);\n- }\n- });\n-\n- // say hi\n- let input_tx_clone = input_tx.clone();\n- global_rt().spawn(async move {\n- tokio::time::sleep(Duration::from_millis(1000)).await;\n- input_tx_clone\n- .send(Msg::default().set_kind(MsgKind::Join))\n- .await\n- .unwrap();\n- });\n-\n- app.run()?;\n-\n- // say goodbye\n- input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n- std::thread::sleep(Duration::from_millis(500));\n-\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"second message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"third message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"fourth message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ //\n+ // let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n+ // let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n+ //\n+ // // let input_loop_fut = input_loop(input_tx);\n+ // let input_tx_clone = input_tx.clone();\n+ // app.on_submit(move |m| {\n+ // debug!(\"sent: {:?}\", m);\n+ // input_tx_clone.blocking_send(m).unwrap();\n+ // });\n+ //\n+ // let topic = if args.topic.is_some() {\n+ // args.topic.clone()\n+ // } else {\n+ // Some(String::from(commit_id.to_string()))\n+ // };\n+ //\n+ // app.topic = topic.clone().unwrap();\n+ //\n+ // let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n+ //\n+ // global_rt().spawn(async move {\n+ // evt_loop(input_rx, peer_tx, topic).await.unwrap();\n+ // });\n+ //\n+ // // recv from peer\n+ // let mut tui_msg_adder = app.add_msg_fn();\n+ // global_rt().spawn(async move {\n+ // while let Some(m) = peer_rx.recv().await {\n+ // debug!(\"recv: {:?}\", m);\n+ // tui_msg_adder(m);\n+ // }\n+ // });\n+ //\n+ // // say hi\n+ // let input_tx_clone = input_tx.clone();\n+ // global_rt().spawn(async move {\n+ // tokio::time::sleep(Duration::from_millis(1000)).await;\n+ // input_tx_clone\n+ // .send(Msg::default().set_kind(MsgKind::Join))\n+ // .await\n+ // .unwrap();\n+ // });\n+ //\n+ // app.run()?;\n+ //\n+ // // say goodbye\n+ // input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n+ // std::thread::sleep(Duration::from_millis(500));\n+ //\n Ok(())\n }\ndiff --git a/src/lib/sub_commands/fetch.rs b/src/lib/sub_commands/fetch.rs\nindex d6343357..2c05425c 100644\n--- a/src/lib/sub_commands/fetch.rs\n+++ b/src/lib/sub_commands/fetch.rs\n@@ -11,7 +11,7 @@ use crate::{\n repo_ref::get_repo_coordinates,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// address pointer to repo announcement\n #[arg(long, action)]\ndiff --git a/src/lib/sub_commands/login.rs b/src/lib/sub_commands/login.rs\nindex 78ea3a58..176a7043 100644\n--- a/src/lib/sub_commands/login.rs\n+++ b/src/lib/sub_commands/login.rs\n@@ -8,7 +8,7 @@ use crate::{\n login,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// don't fetch user metadata and relay list from relays\n #[arg(long, action)]\n","time":1746136255}

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

{"id":"d685d2683288d3247933e2de0f42f6dc273dd410","tree":"4302487b1f8c4b6048436b70bdcd2a857412aeb5","parents":["34b0e967cfa04f4b42079985ad3f3511e0ac51ef"],"author_name":"randymcmillan","author_email":"randymcmillan@protonmail.com","committer_name":"randymcmillan","committer_email":"randymcmillan@protonmail.com","message":"src/lib/sub_commands/chat.rs:intermediate\n\ndiff --git a/src/lib/cli.rs b/src/lib/cli.rs\nindex c253d97c..a32c01fb 100644\n--- a/src/lib/cli.rs\n+++ b/src/lib/cli.rs\n@@ -44,12 +44,12 @@ pub enum Commands {\n Login(sub_commands::login::SubCommandArgs),\n }\n\n-#[derive(Parser)]\n+#[derive(Parser, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatCli {\n- #[command(subcommand)]\n- pub command: ChatCommands,\n+ // #[command(subcommand)]\n+ // pub command: ChatCommands,\n /// remote signer address\n //#[arg(long, global = true)]\n //pub bunker_uri: Option,\n@@ -67,22 +67,22 @@ pub struct ChatCli {\n //pub disable_cli_spinners: bool,\n }\n\n-#[derive(Subcommand)]\n-pub enum ChatCommands {\n- /// update cache with latest updates from nostr\n- Fetch(sub_commands::fetch::SubCommandArgs),\n- /// signal you are this repo's maintainer accepting proposals via\n- /// nostr\n- Init(sub_commands::init::SubCommandArgs),\n- /// issue commits as a proposal\n- Send(sub_commands::send::SubCommandArgs),\n- /// list proposals; checkout, apply or download selected\n- List,\n- /// send proposal revision\n- Push(sub_commands::push::SubCommandArgs),\n- /// fetch and apply new proposal commits / revisions linked to\n- /// branch\n- Pull,\n- /// run with --nsec flag to change npub\n- Login(sub_commands::login::SubCommandArgs),\n-}\n+//#[derive(Subcommand, Debug)]\n+//pub enum ChatCommands {\n+// /// update cache with latest updates from nostr\n+// Fetch(sub_commands::fetch::SubCommandArgs),\n+// /// signal you are this repo's maintainer accepting proposals via\n+// /// nostr\n+// Init(sub_commands::init::SubCommandArgs),\n+// /// issue commits as a proposal\n+// Send(sub_commands::send::SubCommandArgs),\n+// /// list proposals; checkout, apply or download selected\n+// List,\n+// /// send proposal revision\n+// Push(sub_commands::push::SubCommandArgs),\n+// /// fetch and apply new proposal commits / revisions linked to\n+// /// branch\n+// Pull,\n+// /// run with --nsec flag to change npub\n+// Login(sub_commands::login::SubCommandArgs),\n+//}\ndiff --git a/src/lib/sub_commands/chat.rs b/src/lib/sub_commands/chat.rs\nindex 68edc3d3..bec002f5 100644\n--- a/src/lib/sub_commands/chat.rs\n+++ b/src/lib/sub_commands/chat.rs\n@@ -1,6 +1,6 @@\n #![cfg_attr(not(test), warn(clippy::pedantic))]\n #![cfg_attr(not(test), warn(clippy::expect_used))]\n-use crate::cli::ChatCommands;\n+//use crate::cli::ChatCommands;\n use crate::sub_commands::fetch;\n use crate::sub_commands::init;\n use crate::sub_commands::list;\n@@ -44,12 +44,12 @@ use tracing::{debug, info, Level};\n use tracing_subscriber::util::SubscriberInitExt;\n use tracing_subscriber::{fmt, layer::SubscriberExt, EnvFilter, Registry};\n\n-#[derive(Args)]\n+#[derive(Args, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatSubCommand {\n- #[command(subcommand)]\n- command: ChatCommands,\n+ //#[command(subcommand)]\n+ //command: ChatCommands,\n ///// nsec or hex private key\n #[arg(short, long, global = true)]\n nsec: Option,\n@@ -73,366 +73,367 @@ pub struct ChatSubCommand {\n }\n\n pub async fn chat(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- match &sub_command_args.command {\n- ChatCommands::Login(args) => login::launch(&args).await?,\n- ChatCommands::Init(args) => init::launch(&args).await?,\n- ChatCommands::Send(args) => send::launch(&args, true).await?,\n- ChatCommands::List => list::launch().await?,\n- ChatCommands::Pull => pull::launch().await?,\n- ChatCommands::Push(args) => push::launch(&args).await?,\n- ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n-\t\t_ => return Ok(()),\n-\t}\n- //continue\n-\n- run(sub_command_args);\n+ //match &sub_command_args.command {\n+ //// ChatCommands::Login(args) => login::launch(&args).await?,\n+ //// ChatCommands::Init(args) => init::launch(&args).await?,\n+ //// ChatCommands::Send(args) => send::launch(&args, true).await?,\n+ //// ChatCommands::List => list::launch().await?,\n+ //// ChatCommands::Pull => pull::launch().await?,\n+ //// ChatCommands::Push(args) => push::launch(&args).await?,\n+ //// ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n+ //\t_ => { run(sub_command_args).await? }\n+ //}\n+ run(sub_command_args).await?;\n\n Ok(())\n }\n\n pub async fn run(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- let args = sub_command_args;\n-\n- if let Some(name) = args.name.clone() {\n- use std::env;\n- env::set_var(\"USER\", &name);\n- };\n-\n- let level = if args.debug {\n- Level::DEBUG\n- } else if args.trace {\n- Level::TRACE\n- } else if args.info {\n- Level::INFO\n- } else {\n- Level::WARN\n- };\n-\n- let filter = EnvFilter::default()\n- .add_directive(level.into())\n- .add_directive(\"nostr_sdk=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n- .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n- .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n- .add_directive(\"gnostr::message=off\".parse().unwrap())\n- .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n- .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n- //\n- .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n-\n- let subscriber = Registry::default()\n- .with(fmt::layer().with_writer(std::io::stdout))\n- .with(filter);\n-\n- let _ = subscriber.try_init();\n-\n- if args.debug || args.trace {\n- if args.nsec.clone().is_some() {\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n- print!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- print!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n- }\n- }\n- //parse keys from sha256 hash\n- let empty_hash_keys =\n- Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n-\n- if args.nsec.is_some() {\n- //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n-\n- info!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n-\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\")?;\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head()?;\n- let obj = head.resolve()?.peel(ObjectType::Commit)?;\n-\n- //read top commit\n- let commit = obj.peel_to_commit()?;\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"416:commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id);\n- info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n-\n- //// commit based keys\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n- custom_tags.insert(\n- padded_keys.clone().public_key().to_string(),\n- vec![\"GNOSTR\".to_string()],\n- );\n-\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n- info!(\"467:signed_event:\\n{:?}\", signed_event);\n- });\n-\n- //TODO config metadata\n-\n- //access some git info\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- let binding = serialized_commit.clone();\n- let deserialized_commit = deserialize_commit(&repo, &binding)?;\n- info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n-\n- //access commit summary in the deserialized commit\n- info!(\"481:Original commit ID:\\n{}\", commit_id);\n- info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n-\n- //additional checking\n- if commit.id() != deserialized_commit.id() {\n- debug!(\"Commit IDs do not match!\");\n- } else {\n- debug!(\"Commit IDs match!\");\n- }\n-\n- let value: Value = parse_json(&serialized_commit)?;\n- //info!(\"value:\\n{}\", value);\n-\n- // Accessing object elements.\n- if let Some(id) = value.get(\"id\") {\n- info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n- }\n- if let Some(tree) = value.get(\"tree\") {\n- info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n- }\n- // Accessing parent commits (merge may be array)\n- if let Some(parent) = value.get(\"parents\") {\n- if let Value::Array(arr) = parent {\n- if let Some(parent) = arr.get(0) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n- }\n- if let Some(parent) = arr.get(1) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n- }\n- }\n- }\n- if let Some(author_name) = value.get(\"author_name\") {\n- info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(author_email) = value.get(\"author_email\") {\n- info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_name) = value.get(\"committer_name\") {\n- info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_email) = value.get(\"committer_email\") {\n- info!(\n- \"committer_email:\\n{}\",\n- committer_email.as_str().unwrap_or(\"\")\n- );\n- }\n-\n- //split the commit message into a Vec\n- if let Some(message) = value.get(\"message\") {\n- let parts = split_json_string(&message, \"\\n\");\n- for part in parts {\n- info!(\"\\n{}\", part);\n- }\n- debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n- }\n- if let Value::Number(time) = &value[\"time\"] {\n- info!(\"time:\\n{}\", time);\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\").expect(\"\");\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head().expect(\"\");\n- let obj = head\n- .resolve()\n- .expect(\"\")\n- .peel(ObjectType::Commit)\n- .expect(\"\");\n-\n- //read top commit\n- let commit = obj.peel_to_commit().expect(\"\");\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n- //// commit based keys\n- //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n- //create nostr client with commit based keys\n- //let client = Client::new(keys);\n- let client = Client::new(padded_keys.clone());\n- global_rt().spawn(async move {\n- client\n- .add_relay(\"wss://relay.damus.io\")\n- .await\n- .expect(\"failed to add damus relay\");\n- client\n- .add_relay(\"wss://nos.lol\")\n- .await\n- .expect(\"failed to add nos.lol relay\");\n- client.connect().await; // connect() likely doesn't return a Result you can match on\n- let builder = EventBuilder::text_note(serialized_commit.clone());\n- let output = client\n- .send_event_builder(builder)\n- .await\n- .expect(\"589:failed to send event\");\n- info!(\"Event ID: {}\", output.id());\n- info!(\n- \"Event ID BECH32: {}\",\n- output\n- .id()\n- //.public_key()\n- .to_bech32()\n- .expect(\"failed to convert to bech32\")\n- );\n- info!(\"Sent to: {:?}\", output.success);\n- info!(\"Not sent to: {:?}\", output.failed);\n- });\n-\n- //std::process::exit(0);\n-\n- //P2P CHAT\n- let mut app = ui::App::default();\n-\n- //TODO\n- //for line in TITLE.lines() {\n+ println!(\"{:?}\", &sub_command_args);\n+ let chat = chat;\n+\n+ // let args = sub_command_args;\n+ //\n+ // if let Some(name) = args.name.clone() {\n+ // use std::env;\n+ // env::set_var(\"USER\", &name);\n+ // };\n+ //\n+ // let level = if args.debug {\n+ // Level::DEBUG\n+ // } else if args.trace {\n+ // Level::TRACE\n+ // } else if args.info {\n+ // Level::INFO\n+ // } else {\n+ // Level::WARN\n+ // };\n+ //\n+ // let filter = EnvFilter::default()\n+ // .add_directive(level.into())\n+ // .add_directive(\"nostr_sdk=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n+ // .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::message=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n+ // .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n+ // //\n+ // .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n+ //\n+ // let subscriber = Registry::default()\n+ // .with(fmt::layer().with_writer(std::io::stdout))\n+ // .with(filter);\n+ //\n+ // let _ = subscriber.try_init();\n+ //\n+ // if args.debug || args.trace {\n+ // if args.nsec.clone().is_some() {\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ // debug!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // debug!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ // }\n+ // }\n+ // //parse keys from sha256 hash\n+ // let empty_hash_keys =\n+ // Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // if args.nsec.is_some() {\n+ // //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ //\n+ // info!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ //\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\")?;\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head()?;\n+ // let obj = head.resolve()?.peel(ObjectType::Commit)?;\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit()?;\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"416:commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id);\n+ // info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n+ //\n+ // //// commit based keys\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ // custom_tags.insert(\n+ // padded_keys.clone().public_key().to_string(),\n+ // vec![\"GNOSTR\".to_string()],\n+ // );\n+ //\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n+ // info!(\"467:signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // //TODO config metadata\n+ //\n+ // //access some git info\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // let binding = serialized_commit.clone();\n+ // let deserialized_commit = deserialize_commit(&repo, &binding)?;\n+ // info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n+ //\n+ // //access commit summary in the deserialized commit\n+ // info!(\"481:Original commit ID:\\n{}\", commit_id);\n+ // info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n+ //\n+ // //additional checking\n+ // if commit.id() != deserialized_commit.id() {\n+ // debug!(\"Commit IDs do not match!\");\n+ // } else {\n+ // debug!(\"Commit IDs match!\");\n+ // }\n+ //\n+ // let value: Value = parse_json(&serialized_commit)?;\n+ // //info!(\"value:\\n{}\", value);\n+ //\n+ // // Accessing object elements.\n+ // if let Some(id) = value.get(\"id\") {\n+ // info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(tree) = value.get(\"tree\") {\n+ // info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n+ // }\n+ // // Accessing parent commits (merge may be array)\n+ // if let Some(parent) = value.get(\"parents\") {\n+ // if let Value::Array(arr) = parent {\n+ // if let Some(parent) = arr.get(0) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n+ // }\n+ // if let Some(parent) = arr.get(1) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n+ // }\n+ // }\n+ // }\n+ // if let Some(author_name) = value.get(\"author_name\") {\n+ // info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(author_email) = value.get(\"author_email\") {\n+ // info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_name) = value.get(\"committer_name\") {\n+ // info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_email) = value.get(\"committer_email\") {\n+ // info!(\n+ // \"committer_email:\\n{}\",\n+ // committer_email.as_str().unwrap_or(\"\")\n+ // );\n+ // }\n+ //\n+ // //split the commit message into a Vec\n+ // if let Some(message) = value.get(\"message\") {\n+ // let parts = split_json_string(&message, \"\\n\");\n+ // for part in parts {\n+ // info!(\"\\n{}\", part);\n+ // }\n+ // debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Value::Number(time) = &value[\"time\"] {\n+ // info!(\"time:\\n{}\", time);\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\").expect(\"\");\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head().expect(\"\");\n+ // let obj = head\n+ // .resolve()\n+ // .expect(\"\")\n+ // .peel(ObjectType::Commit)\n+ // .expect(\"\");\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit().expect(\"\");\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n+ // //// commit based keys\n+ // //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ // //create nostr client with commit based keys\n+ // //let client = Client::new(keys);\n+ // let client = Client::new(padded_keys.clone());\n+ // global_rt().spawn(async move {\n+ // client\n+ // .add_relay(\"wss://relay.damus.io\")\n+ // .await\n+ // .expect(\"failed to add damus relay\");\n+ // client\n+ // .add_relay(\"wss://nos.lol\")\n+ // .await\n+ // .expect(\"failed to add nos.lol relay\");\n+ // client.connect().await; // connect() likely doesn't return a Result you can match on\n+ // let builder = EventBuilder::text_note(serialized_commit.clone());\n+ // let output = client\n+ // .send_event_builder(builder)\n+ // .await\n+ // .expect(\"589:failed to send event\");\n+ // info!(\"Event ID: {}\", output.id());\n+ // info!(\n+ // \"Event ID BECH32: {}\",\n+ // output\n+ // .id()\n+ // //.public_key()\n+ // .to_bech32()\n+ // .expect(\"failed to convert to bech32\")\n+ // );\n+ // info!(\"Sent to: {:?}\", output.success);\n+ // info!(\"Not sent to: {:?}\", output.failed);\n+ // });\n+ //\n+ // //std::process::exit(0);\n+ //\n+ // //P2P CHAT\n+ // let mut app = ui::App::default();\n+ //\n+ // //TODO\n+ // //for line in TITLE.lines() {\n+ // // app.add_message(\n+ // // Msg::default()\n+ // // .set_content(line.to_string())\n+ // // .set_kind(MsgKind::Raw),\n+ // // );\n+ // //}\n+ //\n+ // use crate::chat::generate_nostr_keys_from_commit_hash;\n+ // let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // info!(\"keys.public_key():\\n{}\", keys.public_key());\n // app.add_message(\n // Msg::default()\n- // .set_content(line.to_string())\n+ // .set_content(keys.public_key().to_string())\n // .set_kind(MsgKind::Raw),\n // );\n- //}\n-\n- use crate::chat::generate_nostr_keys_from_commit_hash;\n- let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- info!(\"keys.public_key():\\n{}\", keys.public_key());\n- app.add_message(\n- Msg::default()\n- .set_content(keys.public_key().to_string())\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"second message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"third message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"fourth message\"))\n- .set_kind(MsgKind::Raw),\n- );\n-\n- let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n- let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n-\n- // let input_loop_fut = input_loop(input_tx);\n- let input_tx_clone = input_tx.clone();\n- app.on_submit(move |m| {\n- debug!(\"sent: {:?}\", m);\n- input_tx_clone.blocking_send(m).unwrap();\n- });\n-\n- let topic = if args.topic.is_some() {\n- args.topic.clone()\n- } else {\n- Some(String::from(commit_id.to_string()))\n- };\n-\n- app.topic = topic.clone().unwrap();\n-\n- let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n-\n- global_rt().spawn(async move {\n- evt_loop(input_rx, peer_tx, topic).await.unwrap();\n- });\n-\n- // recv from peer\n- let mut tui_msg_adder = app.add_msg_fn();\n- global_rt().spawn(async move {\n- while let Some(m) = peer_rx.recv().await {\n- debug!(\"recv: {:?}\", m);\n- tui_msg_adder(m);\n- }\n- });\n-\n- // say hi\n- let input_tx_clone = input_tx.clone();\n- global_rt().spawn(async move {\n- tokio::time::sleep(Duration::from_millis(1000)).await;\n- input_tx_clone\n- .send(Msg::default().set_kind(MsgKind::Join))\n- .await\n- .unwrap();\n- });\n-\n- app.run()?;\n-\n- // say goodbye\n- input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n- std::thread::sleep(Duration::from_millis(500));\n-\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"second message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"third message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"fourth message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ //\n+ // let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n+ // let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n+ //\n+ // // let input_loop_fut = input_loop(input_tx);\n+ // let input_tx_clone = input_tx.clone();\n+ // app.on_submit(move |m| {\n+ // debug!(\"sent: {:?}\", m);\n+ // input_tx_clone.blocking_send(m).unwrap();\n+ // });\n+ //\n+ // let topic = if args.topic.is_some() {\n+ // args.topic.clone()\n+ // } else {\n+ // Some(String::from(commit_id.to_string()))\n+ // };\n+ //\n+ // app.topic = topic.clone().unwrap();\n+ //\n+ // let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n+ //\n+ // global_rt().spawn(async move {\n+ // evt_loop(input_rx, peer_tx, topic).await.unwrap();\n+ // });\n+ //\n+ // // recv from peer\n+ // let mut tui_msg_adder = app.add_msg_fn();\n+ // global_rt().spawn(async move {\n+ // while let Some(m) = peer_rx.recv().await {\n+ // debug!(\"recv: {:?}\", m);\n+ // tui_msg_adder(m);\n+ // }\n+ // });\n+ //\n+ // // say hi\n+ // let input_tx_clone = input_tx.clone();\n+ // global_rt().spawn(async move {\n+ // tokio::time::sleep(Duration::from_millis(1000)).await;\n+ // input_tx_clone\n+ // .send(Msg::default().set_kind(MsgKind::Join))\n+ // .await\n+ // .unwrap();\n+ // });\n+ //\n+ // app.run()?;\n+ //\n+ // // say goodbye\n+ // input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n+ // std::thread::sleep(Duration::from_millis(500));\n+ //\n Ok(())\n }\ndiff --git a/src/lib/sub_commands/fetch.rs b/src/lib/sub_commands/fetch.rs\nindex d6343357..2c05425c 100644\n--- a/src/lib/sub_commands/fetch.rs\n+++ b/src/lib/sub_commands/fetch.rs\n@@ -11,7 +11,7 @@ use crate::{\n repo_ref::get_repo_coordinates,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// address pointer to repo announcement\n #[arg(long, action)]\ndiff --git a/src/lib/sub_commands/login.rs b/src/lib/sub_commands/login.rs\nindex 78ea3a58..176a7043 100644\n--- a/src/lib/sub_commands/login.rs\n+++ b/src/lib/sub_commands/login.rs\n@@ -8,7 +8,7 @@ use crate::{\n login,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// don't fetch user metadata and relay list from relays\n #[arg(long, action)]\n","time":1746136255}

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

{"id":"d685d2683288d3247933e2de0f42f6dc273dd410","tree":"4302487b1f8c4b6048436b70bdcd2a857412aeb5","parents":["34b0e967cfa04f4b42079985ad3f3511e0ac51ef"],"author_name":"randymcmillan","author_email":"randymcmillan@protonmail.com","committer_name":"randymcmillan","committer_email":"randymcmillan@protonmail.com","message":"src/lib/sub_commands/chat.rs:intermediate\n\ndiff --git a/src/lib/cli.rs b/src/lib/cli.rs\nindex c253d97c..a32c01fb 100644\n--- a/src/lib/cli.rs\n+++ b/src/lib/cli.rs\n@@ -44,12 +44,12 @@ pub enum Commands {\n Login(sub_commands::login::SubCommandArgs),\n }\n\n-#[derive(Parser)]\n+#[derive(Parser, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatCli {\n- #[command(subcommand)]\n- pub command: ChatCommands,\n+ // #[command(subcommand)]\n+ // pub command: ChatCommands,\n /// remote signer address\n //#[arg(long, global = true)]\n //pub bunker_uri: Option,\n@@ -67,22 +67,22 @@ pub struct ChatCli {\n //pub disable_cli_spinners: bool,\n }\n\n-#[derive(Subcommand)]\n-pub enum ChatCommands {\n- /// update cache with latest updates from nostr\n- Fetch(sub_commands::fetch::SubCommandArgs),\n- /// signal you are this repo's maintainer accepting proposals via\n- /// nostr\n- Init(sub_commands::init::SubCommandArgs),\n- /// issue commits as a proposal\n- Send(sub_commands::send::SubCommandArgs),\n- /// list proposals; checkout, apply or download selected\n- List,\n- /// send proposal revision\n- Push(sub_commands::push::SubCommandArgs),\n- /// fetch and apply new proposal commits / revisions linked to\n- /// branch\n- Pull,\n- /// run with --nsec flag to change npub\n- Login(sub_commands::login::SubCommandArgs),\n-}\n+//#[derive(Subcommand, Debug)]\n+//pub enum ChatCommands {\n+// /// update cache with latest updates from nostr\n+// Fetch(sub_commands::fetch::SubCommandArgs),\n+// /// signal you are this repo's maintainer accepting proposals via\n+// /// nostr\n+// Init(sub_commands::init::SubCommandArgs),\n+// /// issue commits as a proposal\n+// Send(sub_commands::send::SubCommandArgs),\n+// /// list proposals; checkout, apply or download selected\n+// List,\n+// /// send proposal revision\n+// Push(sub_commands::push::SubCommandArgs),\n+// /// fetch and apply new proposal commits / revisions linked to\n+// /// branch\n+// Pull,\n+// /// run with --nsec flag to change npub\n+// Login(sub_commands::login::SubCommandArgs),\n+//}\ndiff --git a/src/lib/sub_commands/chat.rs b/src/lib/sub_commands/chat.rs\nindex 68edc3d3..bec002f5 100644\n--- a/src/lib/sub_commands/chat.rs\n+++ b/src/lib/sub_commands/chat.rs\n@@ -1,6 +1,6 @@\n #![cfg_attr(not(test), warn(clippy::pedantic))]\n #![cfg_attr(not(test), warn(clippy::expect_used))]\n-use crate::cli::ChatCommands;\n+//use crate::cli::ChatCommands;\n use crate::sub_commands::fetch;\n use crate::sub_commands::init;\n use crate::sub_commands::list;\n@@ -44,12 +44,12 @@ use tracing::{debug, info, Level};\n use tracing_subscriber::util::SubscriberInitExt;\n use tracing_subscriber::{fmt, layer::SubscriberExt, EnvFilter, Registry};\n\n-#[derive(Args)]\n+#[derive(Args, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatSubCommand {\n- #[command(subcommand)]\n- command: ChatCommands,\n+ //#[command(subcommand)]\n+ //command: ChatCommands,\n ///// nsec or hex private key\n #[arg(short, long, global = true)]\n nsec: Option,\n@@ -73,366 +73,367 @@ pub struct ChatSubCommand {\n }\n\n pub async fn chat(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- match &sub_command_args.command {\n- ChatCommands::Login(args) => login::launch(&args).await?,\n- ChatCommands::Init(args) => init::launch(&args).await?,\n- ChatCommands::Send(args) => send::launch(&args, true).await?,\n- ChatCommands::List => list::launch().await?,\n- ChatCommands::Pull => pull::launch().await?,\n- ChatCommands::Push(args) => push::launch(&args).await?,\n- ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n-\t\t_ => return Ok(()),\n-\t}\n- //continue\n-\n- run(sub_command_args);\n+ //match &sub_command_args.command {\n+ //// ChatCommands::Login(args) => login::launch(&args).await?,\n+ //// ChatCommands::Init(args) => init::launch(&args).await?,\n+ //// ChatCommands::Send(args) => send::launch(&args, true).await?,\n+ //// ChatCommands::List => list::launch().await?,\n+ //// ChatCommands::Pull => pull::launch().await?,\n+ //// ChatCommands::Push(args) => push::launch(&args).await?,\n+ //// ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n+ //\t_ => { run(sub_command_args).await? }\n+ //}\n+ run(sub_command_args).await?;\n\n Ok(())\n }\n\n pub async fn run(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- let args = sub_command_args;\n-\n- if let Some(name) = args.name.clone() {\n- use std::env;\n- env::set_var(\"USER\", &name);\n- };\n-\n- let level = if args.debug {\n- Level::DEBUG\n- } else if args.trace {\n- Level::TRACE\n- } else if args.info {\n- Level::INFO\n- } else {\n- Level::WARN\n- };\n-\n- let filter = EnvFilter::default()\n- .add_directive(level.into())\n- .add_directive(\"nostr_sdk=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n- .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n- .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n- .add_directive(\"gnostr::message=off\".parse().unwrap())\n- .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n- .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n- //\n- .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n-\n- let subscriber = Registry::default()\n- .with(fmt::layer().with_writer(std::io::stdout))\n- .with(filter);\n-\n- let _ = subscriber.try_init();\n-\n- if args.debug || args.trace {\n- if args.nsec.clone().is_some() {\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n- print!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- print!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n- }\n- }\n- //parse keys from sha256 hash\n- let empty_hash_keys =\n- Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n-\n- if args.nsec.is_some() {\n- //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n-\n- info!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n-\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\")?;\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head()?;\n- let obj = head.resolve()?.peel(ObjectType::Commit)?;\n-\n- //read top commit\n- let commit = obj.peel_to_commit()?;\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"416:commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id);\n- info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n-\n- //// commit based keys\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n- custom_tags.insert(\n- padded_keys.clone().public_key().to_string(),\n- vec![\"GNOSTR\".to_string()],\n- );\n-\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n- info!(\"467:signed_event:\\n{:?}\", signed_event);\n- });\n-\n- //TODO config metadata\n-\n- //access some git info\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- let binding = serialized_commit.clone();\n- let deserialized_commit = deserialize_commit(&repo, &binding)?;\n- info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n-\n- //access commit summary in the deserialized commit\n- info!(\"481:Original commit ID:\\n{}\", commit_id);\n- info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n-\n- //additional checking\n- if commit.id() != deserialized_commit.id() {\n- debug!(\"Commit IDs do not match!\");\n- } else {\n- debug!(\"Commit IDs match!\");\n- }\n-\n- let value: Value = parse_json(&serialized_commit)?;\n- //info!(\"value:\\n{}\", value);\n-\n- // Accessing object elements.\n- if let Some(id) = value.get(\"id\") {\n- info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n- }\n- if let Some(tree) = value.get(\"tree\") {\n- info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n- }\n- // Accessing parent commits (merge may be array)\n- if let Some(parent) = value.get(\"parents\") {\n- if let Value::Array(arr) = parent {\n- if let Some(parent) = arr.get(0) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n- }\n- if let Some(parent) = arr.get(1) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n- }\n- }\n- }\n- if let Some(author_name) = value.get(\"author_name\") {\n- info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(author_email) = value.get(\"author_email\") {\n- info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_name) = value.get(\"committer_name\") {\n- info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_email) = value.get(\"committer_email\") {\n- info!(\n- \"committer_email:\\n{}\",\n- committer_email.as_str().unwrap_or(\"\")\n- );\n- }\n-\n- //split the commit message into a Vec\n- if let Some(message) = value.get(\"message\") {\n- let parts = split_json_string(&message, \"\\n\");\n- for part in parts {\n- info!(\"\\n{}\", part);\n- }\n- debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n- }\n- if let Value::Number(time) = &value[\"time\"] {\n- info!(\"time:\\n{}\", time);\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\").expect(\"\");\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head().expect(\"\");\n- let obj = head\n- .resolve()\n- .expect(\"\")\n- .peel(ObjectType::Commit)\n- .expect(\"\");\n-\n- //read top commit\n- let commit = obj.peel_to_commit().expect(\"\");\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n- //// commit based keys\n- //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n- //create nostr client with commit based keys\n- //let client = Client::new(keys);\n- let client = Client::new(padded_keys.clone());\n- global_rt().spawn(async move {\n- client\n- .add_relay(\"wss://relay.damus.io\")\n- .await\n- .expect(\"failed to add damus relay\");\n- client\n- .add_relay(\"wss://nos.lol\")\n- .await\n- .expect(\"failed to add nos.lol relay\");\n- client.connect().await; // connect() likely doesn't return a Result you can match on\n- let builder = EventBuilder::text_note(serialized_commit.clone());\n- let output = client\n- .send_event_builder(builder)\n- .await\n- .expect(\"589:failed to send event\");\n- info!(\"Event ID: {}\", output.id());\n- info!(\n- \"Event ID BECH32: {}\",\n- output\n- .id()\n- //.public_key()\n- .to_bech32()\n- .expect(\"failed to convert to bech32\")\n- );\n- info!(\"Sent to: {:?}\", output.success);\n- info!(\"Not sent to: {:?}\", output.failed);\n- });\n-\n- //std::process::exit(0);\n-\n- //P2P CHAT\n- let mut app = ui::App::default();\n-\n- //TODO\n- //for line in TITLE.lines() {\n+ println!(\"{:?}\", &sub_command_args);\n+ let chat = chat;\n+\n+ // let args = sub_command_args;\n+ //\n+ // if let Some(name) = args.name.clone() {\n+ // use std::env;\n+ // env::set_var(\"USER\", &name);\n+ // };\n+ //\n+ // let level = if args.debug {\n+ // Level::DEBUG\n+ // } else if args.trace {\n+ // Level::TRACE\n+ // } else if args.info {\n+ // Level::INFO\n+ // } else {\n+ // Level::WARN\n+ // };\n+ //\n+ // let filter = EnvFilter::default()\n+ // .add_directive(level.into())\n+ // .add_directive(\"nostr_sdk=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n+ // .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::message=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n+ // .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n+ // //\n+ // .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n+ //\n+ // let subscriber = Registry::default()\n+ // .with(fmt::layer().with_writer(std::io::stdout))\n+ // .with(filter);\n+ //\n+ // let _ = subscriber.try_init();\n+ //\n+ // if args.debug || args.trace {\n+ // if args.nsec.clone().is_some() {\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ // debug!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // debug!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ // }\n+ // }\n+ // //parse keys from sha256 hash\n+ // let empty_hash_keys =\n+ // Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // if args.nsec.is_some() {\n+ // //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ //\n+ // info!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ //\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\")?;\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head()?;\n+ // let obj = head.resolve()?.peel(ObjectType::Commit)?;\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit()?;\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"416:commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id);\n+ // info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n+ //\n+ // //// commit based keys\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ // custom_tags.insert(\n+ // padded_keys.clone().public_key().to_string(),\n+ // vec![\"GNOSTR\".to_string()],\n+ // );\n+ //\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n+ // info!(\"467:signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // //TODO config metadata\n+ //\n+ // //access some git info\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // let binding = serialized_commit.clone();\n+ // let deserialized_commit = deserialize_commit(&repo, &binding)?;\n+ // info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n+ //\n+ // //access commit summary in the deserialized commit\n+ // info!(\"481:Original commit ID:\\n{}\", commit_id);\n+ // info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n+ //\n+ // //additional checking\n+ // if commit.id() != deserialized_commit.id() {\n+ // debug!(\"Commit IDs do not match!\");\n+ // } else {\n+ // debug!(\"Commit IDs match!\");\n+ // }\n+ //\n+ // let value: Value = parse_json(&serialized_commit)?;\n+ // //info!(\"value:\\n{}\", value);\n+ //\n+ // // Accessing object elements.\n+ // if let Some(id) = value.get(\"id\") {\n+ // info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(tree) = value.get(\"tree\") {\n+ // info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n+ // }\n+ // // Accessing parent commits (merge may be array)\n+ // if let Some(parent) = value.get(\"parents\") {\n+ // if let Value::Array(arr) = parent {\n+ // if let Some(parent) = arr.get(0) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n+ // }\n+ // if let Some(parent) = arr.get(1) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n+ // }\n+ // }\n+ // }\n+ // if let Some(author_name) = value.get(\"author_name\") {\n+ // info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(author_email) = value.get(\"author_email\") {\n+ // info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_name) = value.get(\"committer_name\") {\n+ // info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_email) = value.get(\"committer_email\") {\n+ // info!(\n+ // \"committer_email:\\n{}\",\n+ // committer_email.as_str().unwrap_or(\"\")\n+ // );\n+ // }\n+ //\n+ // //split the commit message into a Vec\n+ // if let Some(message) = value.get(\"message\") {\n+ // let parts = split_json_string(&message, \"\\n\");\n+ // for part in parts {\n+ // info!(\"\\n{}\", part);\n+ // }\n+ // debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Value::Number(time) = &value[\"time\"] {\n+ // info!(\"time:\\n{}\", time);\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\").expect(\"\");\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head().expect(\"\");\n+ // let obj = head\n+ // .resolve()\n+ // .expect(\"\")\n+ // .peel(ObjectType::Commit)\n+ // .expect(\"\");\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit().expect(\"\");\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n+ // //// commit based keys\n+ // //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ // //create nostr client with commit based keys\n+ // //let client = Client::new(keys);\n+ // let client = Client::new(padded_keys.clone());\n+ // global_rt().spawn(async move {\n+ // client\n+ // .add_relay(\"wss://relay.damus.io\")\n+ // .await\n+ // .expect(\"failed to add damus relay\");\n+ // client\n+ // .add_relay(\"wss://nos.lol\")\n+ // .await\n+ // .expect(\"failed to add nos.lol relay\");\n+ // client.connect().await; // connect() likely doesn't return a Result you can match on\n+ // let builder = EventBuilder::text_note(serialized_commit.clone());\n+ // let output = client\n+ // .send_event_builder(builder)\n+ // .await\n+ // .expect(\"589:failed to send event\");\n+ // info!(\"Event ID: {}\", output.id());\n+ // info!(\n+ // \"Event ID BECH32: {}\",\n+ // output\n+ // .id()\n+ // //.public_key()\n+ // .to_bech32()\n+ // .expect(\"failed to convert to bech32\")\n+ // );\n+ // info!(\"Sent to: {:?}\", output.success);\n+ // info!(\"Not sent to: {:?}\", output.failed);\n+ // });\n+ //\n+ // //std::process::exit(0);\n+ //\n+ // //P2P CHAT\n+ // let mut app = ui::App::default();\n+ //\n+ // //TODO\n+ // //for line in TITLE.lines() {\n+ // // app.add_message(\n+ // // Msg::default()\n+ // // .set_content(line.to_string())\n+ // // .set_kind(MsgKind::Raw),\n+ // // );\n+ // //}\n+ //\n+ // use crate::chat::generate_nostr_keys_from_commit_hash;\n+ // let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // info!(\"keys.public_key():\\n{}\", keys.public_key());\n // app.add_message(\n // Msg::default()\n- // .set_content(line.to_string())\n+ // .set_content(keys.public_key().to_string())\n // .set_kind(MsgKind::Raw),\n // );\n- //}\n-\n- use crate::chat::generate_nostr_keys_from_commit_hash;\n- let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- info!(\"keys.public_key():\\n{}\", keys.public_key());\n- app.add_message(\n- Msg::default()\n- .set_content(keys.public_key().to_string())\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"second message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"third message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"fourth message\"))\n- .set_kind(MsgKind::Raw),\n- );\n-\n- let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n- let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n-\n- // let input_loop_fut = input_loop(input_tx);\n- let input_tx_clone = input_tx.clone();\n- app.on_submit(move |m| {\n- debug!(\"sent: {:?}\", m);\n- input_tx_clone.blocking_send(m).unwrap();\n- });\n-\n- let topic = if args.topic.is_some() {\n- args.topic.clone()\n- } else {\n- Some(String::from(commit_id.to_string()))\n- };\n-\n- app.topic = topic.clone().unwrap();\n-\n- let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n-\n- global_rt().spawn(async move {\n- evt_loop(input_rx, peer_tx, topic).await.unwrap();\n- });\n-\n- // recv from peer\n- let mut tui_msg_adder = app.add_msg_fn();\n- global_rt().spawn(async move {\n- while let Some(m) = peer_rx.recv().await {\n- debug!(\"recv: {:?}\", m);\n- tui_msg_adder(m);\n- }\n- });\n-\n- // say hi\n- let input_tx_clone = input_tx.clone();\n- global_rt().spawn(async move {\n- tokio::time::sleep(Duration::from_millis(1000)).await;\n- input_tx_clone\n- .send(Msg::default().set_kind(MsgKind::Join))\n- .await\n- .unwrap();\n- });\n-\n- app.run()?;\n-\n- // say goodbye\n- input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n- std::thread::sleep(Duration::from_millis(500));\n-\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"second message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"third message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"fourth message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ //\n+ // let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n+ // let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n+ //\n+ // // let input_loop_fut = input_loop(input_tx);\n+ // let input_tx_clone = input_tx.clone();\n+ // app.on_submit(move |m| {\n+ // debug!(\"sent: {:?}\", m);\n+ // input_tx_clone.blocking_send(m).unwrap();\n+ // });\n+ //\n+ // let topic = if args.topic.is_some() {\n+ // args.topic.clone()\n+ // } else {\n+ // Some(String::from(commit_id.to_string()))\n+ // };\n+ //\n+ // app.topic = topic.clone().unwrap();\n+ //\n+ // let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n+ //\n+ // global_rt().spawn(async move {\n+ // evt_loop(input_rx, peer_tx, topic).await.unwrap();\n+ // });\n+ //\n+ // // recv from peer\n+ // let mut tui_msg_adder = app.add_msg_fn();\n+ // global_rt().spawn(async move {\n+ // while let Some(m) = peer_rx.recv().await {\n+ // debug!(\"recv: {:?}\", m);\n+ // tui_msg_adder(m);\n+ // }\n+ // });\n+ //\n+ // // say hi\n+ // let input_tx_clone = input_tx.clone();\n+ // global_rt().spawn(async move {\n+ // tokio::time::sleep(Duration::from_millis(1000)).await;\n+ // input_tx_clone\n+ // .send(Msg::default().set_kind(MsgKind::Join))\n+ // .await\n+ // .unwrap();\n+ // });\n+ //\n+ // app.run()?;\n+ //\n+ // // say goodbye\n+ // input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n+ // std::thread::sleep(Duration::from_millis(500));\n+ //\n Ok(())\n }\ndiff --git a/src/lib/sub_commands/fetch.rs b/src/lib/sub_commands/fetch.rs\nindex d6343357..2c05425c 100644\n--- a/src/lib/sub_commands/fetch.rs\n+++ b/src/lib/sub_commands/fetch.rs\n@@ -11,7 +11,7 @@ use crate::{\n repo_ref::get_repo_coordinates,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// address pointer to repo announcement\n #[arg(long, action)]\ndiff --git a/src/lib/sub_commands/login.rs b/src/lib/sub_commands/login.rs\nindex 78ea3a58..176a7043 100644\n--- a/src/lib/sub_commands/login.rs\n+++ b/src/lib/sub_commands/login.rs\n@@ -8,7 +8,7 @@ use crate::{\n login,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// don't fetch user metadata and relay list from relays\n #[arg(long, action)]\n","time":1746136255}

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

{"id":"d685d2683288d3247933e2de0f42f6dc273dd410","tree":"4302487b1f8c4b6048436b70bdcd2a857412aeb5","parents":["34b0e967cfa04f4b42079985ad3f3511e0ac51ef"],"author_name":"randymcmillan","author_email":"randymcmillan@protonmail.com","committer_name":"randymcmillan","committer_email":"randymcmillan@protonmail.com","message":"src/lib/sub_commands/chat.rs:intermediate\n\ndiff --git a/src/lib/cli.rs b/src/lib/cli.rs\nindex c253d97c..a32c01fb 100644\n--- a/src/lib/cli.rs\n+++ b/src/lib/cli.rs\n@@ -44,12 +44,12 @@ pub enum Commands {\n Login(sub_commands::login::SubCommandArgs),\n }\n\n-#[derive(Parser)]\n+#[derive(Parser, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatCli {\n- #[command(subcommand)]\n- pub command: ChatCommands,\n+ // #[command(subcommand)]\n+ // pub command: ChatCommands,\n /// remote signer address\n //#[arg(long, global = true)]\n //pub bunker_uri: Option,\n@@ -67,22 +67,22 @@ pub struct ChatCli {\n //pub disable_cli_spinners: bool,\n }\n\n-#[derive(Subcommand)]\n-pub enum ChatCommands {\n- /// update cache with latest updates from nostr\n- Fetch(sub_commands::fetch::SubCommandArgs),\n- /// signal you are this repo's maintainer accepting proposals via\n- /// nostr\n- Init(sub_commands::init::SubCommandArgs),\n- /// issue commits as a proposal\n- Send(sub_commands::send::SubCommandArgs),\n- /// list proposals; checkout, apply or download selected\n- List,\n- /// send proposal revision\n- Push(sub_commands::push::SubCommandArgs),\n- /// fetch and apply new proposal commits / revisions linked to\n- /// branch\n- Pull,\n- /// run with --nsec flag to change npub\n- Login(sub_commands::login::SubCommandArgs),\n-}\n+//#[derive(Subcommand, Debug)]\n+//pub enum ChatCommands {\n+// /// update cache with latest updates from nostr\n+// Fetch(sub_commands::fetch::SubCommandArgs),\n+// /// signal you are this repo's maintainer accepting proposals via\n+// /// nostr\n+// Init(sub_commands::init::SubCommandArgs),\n+// /// issue commits as a proposal\n+// Send(sub_commands::send::SubCommandArgs),\n+// /// list proposals; checkout, apply or download selected\n+// List,\n+// /// send proposal revision\n+// Push(sub_commands::push::SubCommandArgs),\n+// /// fetch and apply new proposal commits / revisions linked to\n+// /// branch\n+// Pull,\n+// /// run with --nsec flag to change npub\n+// Login(sub_commands::login::SubCommandArgs),\n+//}\ndiff --git a/src/lib/sub_commands/chat.rs b/src/lib/sub_commands/chat.rs\nindex 68edc3d3..bec002f5 100644\n--- a/src/lib/sub_commands/chat.rs\n+++ b/src/lib/sub_commands/chat.rs\n@@ -1,6 +1,6 @@\n #![cfg_attr(not(test), warn(clippy::pedantic))]\n #![cfg_attr(not(test), warn(clippy::expect_used))]\n-use crate::cli::ChatCommands;\n+//use crate::cli::ChatCommands;\n use crate::sub_commands::fetch;\n use crate::sub_commands::init;\n use crate::sub_commands::list;\n@@ -44,12 +44,12 @@ use tracing::{debug, info, Level};\n use tracing_subscriber::util::SubscriberInitExt;\n use tracing_subscriber::{fmt, layer::SubscriberExt, EnvFilter, Registry};\n\n-#[derive(Args)]\n+#[derive(Args, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatSubCommand {\n- #[command(subcommand)]\n- command: ChatCommands,\n+ //#[command(subcommand)]\n+ //command: ChatCommands,\n ///// nsec or hex private key\n #[arg(short, long, global = true)]\n nsec: Option,\n@@ -73,366 +73,367 @@ pub struct ChatSubCommand {\n }\n\n pub async fn chat(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- match &sub_command_args.command {\n- ChatCommands::Login(args) => login::launch(&args).await?,\n- ChatCommands::Init(args) => init::launch(&args).await?,\n- ChatCommands::Send(args) => send::launch(&args, true).await?,\n- ChatCommands::List => list::launch().await?,\n- ChatCommands::Pull => pull::launch().await?,\n- ChatCommands::Push(args) => push::launch(&args).await?,\n- ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n-\t\t_ => return Ok(()),\n-\t}\n- //continue\n-\n- run(sub_command_args);\n+ //match &sub_command_args.command {\n+ //// ChatCommands::Login(args) => login::launch(&args).await?,\n+ //// ChatCommands::Init(args) => init::launch(&args).await?,\n+ //// ChatCommands::Send(args) => send::launch(&args, true).await?,\n+ //// ChatCommands::List => list::launch().await?,\n+ //// ChatCommands::Pull => pull::launch().await?,\n+ //// ChatCommands::Push(args) => push::launch(&args).await?,\n+ //// ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n+ //\t_ => { run(sub_command_args).await? }\n+ //}\n+ run(sub_command_args).await?;\n\n Ok(())\n }\n\n pub async fn run(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- let args = sub_command_args;\n-\n- if let Some(name) = args.name.clone() {\n- use std::env;\n- env::set_var(\"USER\", &name);\n- };\n-\n- let level = if args.debug {\n- Level::DEBUG\n- } else if args.trace {\n- Level::TRACE\n- } else if args.info {\n- Level::INFO\n- } else {\n- Level::WARN\n- };\n-\n- let filter = EnvFilter::default()\n- .add_directive(level.into())\n- .add_directive(\"nostr_sdk=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n- .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n- .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n- .add_directive(\"gnostr::message=off\".parse().unwrap())\n- .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n- .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n- //\n- .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n-\n- let subscriber = Registry::default()\n- .with(fmt::layer().with_writer(std::io::stdout))\n- .with(filter);\n-\n- let _ = subscriber.try_init();\n-\n- if args.debug || args.trace {\n- if args.nsec.clone().is_some() {\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n- print!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- print!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n- }\n- }\n- //parse keys from sha256 hash\n- let empty_hash_keys =\n- Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n-\n- if args.nsec.is_some() {\n- //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n-\n- info!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n-\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\")?;\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head()?;\n- let obj = head.resolve()?.peel(ObjectType::Commit)?;\n-\n- //read top commit\n- let commit = obj.peel_to_commit()?;\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"416:commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id);\n- info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n-\n- //// commit based keys\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n- custom_tags.insert(\n- padded_keys.clone().public_key().to_string(),\n- vec![\"GNOSTR\".to_string()],\n- );\n-\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n- info!(\"467:signed_event:\\n{:?}\", signed_event);\n- });\n-\n- //TODO config metadata\n-\n- //access some git info\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- let binding = serialized_commit.clone();\n- let deserialized_commit = deserialize_commit(&repo, &binding)?;\n- info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n-\n- //access commit summary in the deserialized commit\n- info!(\"481:Original commit ID:\\n{}\", commit_id);\n- info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n-\n- //additional checking\n- if commit.id() != deserialized_commit.id() {\n- debug!(\"Commit IDs do not match!\");\n- } else {\n- debug!(\"Commit IDs match!\");\n- }\n-\n- let value: Value = parse_json(&serialized_commit)?;\n- //info!(\"value:\\n{}\", value);\n-\n- // Accessing object elements.\n- if let Some(id) = value.get(\"id\") {\n- info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n- }\n- if let Some(tree) = value.get(\"tree\") {\n- info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n- }\n- // Accessing parent commits (merge may be array)\n- if let Some(parent) = value.get(\"parents\") {\n- if let Value::Array(arr) = parent {\n- if let Some(parent) = arr.get(0) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n- }\n- if let Some(parent) = arr.get(1) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n- }\n- }\n- }\n- if let Some(author_name) = value.get(\"author_name\") {\n- info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(author_email) = value.get(\"author_email\") {\n- info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_name) = value.get(\"committer_name\") {\n- info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_email) = value.get(\"committer_email\") {\n- info!(\n- \"committer_email:\\n{}\",\n- committer_email.as_str().unwrap_or(\"\")\n- );\n- }\n-\n- //split the commit message into a Vec\n- if let Some(message) = value.get(\"message\") {\n- let parts = split_json_string(&message, \"\\n\");\n- for part in parts {\n- info!(\"\\n{}\", part);\n- }\n- debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n- }\n- if let Value::Number(time) = &value[\"time\"] {\n- info!(\"time:\\n{}\", time);\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\").expect(\"\");\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head().expect(\"\");\n- let obj = head\n- .resolve()\n- .expect(\"\")\n- .peel(ObjectType::Commit)\n- .expect(\"\");\n-\n- //read top commit\n- let commit = obj.peel_to_commit().expect(\"\");\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n- //// commit based keys\n- //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n- //create nostr client with commit based keys\n- //let client = Client::new(keys);\n- let client = Client::new(padded_keys.clone());\n- global_rt().spawn(async move {\n- client\n- .add_relay(\"wss://relay.damus.io\")\n- .await\n- .expect(\"failed to add damus relay\");\n- client\n- .add_relay(\"wss://nos.lol\")\n- .await\n- .expect(\"failed to add nos.lol relay\");\n- client.connect().await; // connect() likely doesn't return a Result you can match on\n- let builder = EventBuilder::text_note(serialized_commit.clone());\n- let output = client\n- .send_event_builder(builder)\n- .await\n- .expect(\"589:failed to send event\");\n- info!(\"Event ID: {}\", output.id());\n- info!(\n- \"Event ID BECH32: {}\",\n- output\n- .id()\n- //.public_key()\n- .to_bech32()\n- .expect(\"failed to convert to bech32\")\n- );\n- info!(\"Sent to: {:?}\", output.success);\n- info!(\"Not sent to: {:?}\", output.failed);\n- });\n-\n- //std::process::exit(0);\n-\n- //P2P CHAT\n- let mut app = ui::App::default();\n-\n- //TODO\n- //for line in TITLE.lines() {\n+ println!(\"{:?}\", &sub_command_args);\n+ let chat = chat;\n+\n+ // let args = sub_command_args;\n+ //\n+ // if let Some(name) = args.name.clone() {\n+ // use std::env;\n+ // env::set_var(\"USER\", &name);\n+ // };\n+ //\n+ // let level = if args.debug {\n+ // Level::DEBUG\n+ // } else if args.trace {\n+ // Level::TRACE\n+ // } else if args.info {\n+ // Level::INFO\n+ // } else {\n+ // Level::WARN\n+ // };\n+ //\n+ // let filter = EnvFilter::default()\n+ // .add_directive(level.into())\n+ // .add_directive(\"nostr_sdk=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n+ // .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::message=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n+ // .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n+ // //\n+ // .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n+ //\n+ // let subscriber = Registry::default()\n+ // .with(fmt::layer().with_writer(std::io::stdout))\n+ // .with(filter);\n+ //\n+ // let _ = subscriber.try_init();\n+ //\n+ // if args.debug || args.trace {\n+ // if args.nsec.clone().is_some() {\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ // debug!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // debug!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ // }\n+ // }\n+ // //parse keys from sha256 hash\n+ // let empty_hash_keys =\n+ // Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // if args.nsec.is_some() {\n+ // //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ //\n+ // info!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ //\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\")?;\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head()?;\n+ // let obj = head.resolve()?.peel(ObjectType::Commit)?;\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit()?;\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"416:commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id);\n+ // info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n+ //\n+ // //// commit based keys\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ // custom_tags.insert(\n+ // padded_keys.clone().public_key().to_string(),\n+ // vec![\"GNOSTR\".to_string()],\n+ // );\n+ //\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n+ // info!(\"467:signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // //TODO config metadata\n+ //\n+ // //access some git info\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // let binding = serialized_commit.clone();\n+ // let deserialized_commit = deserialize_commit(&repo, &binding)?;\n+ // info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n+ //\n+ // //access commit summary in the deserialized commit\n+ // info!(\"481:Original commit ID:\\n{}\", commit_id);\n+ // info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n+ //\n+ // //additional checking\n+ // if commit.id() != deserialized_commit.id() {\n+ // debug!(\"Commit IDs do not match!\");\n+ // } else {\n+ // debug!(\"Commit IDs match!\");\n+ // }\n+ //\n+ // let value: Value = parse_json(&serialized_commit)?;\n+ // //info!(\"value:\\n{}\", value);\n+ //\n+ // // Accessing object elements.\n+ // if let Some(id) = value.get(\"id\") {\n+ // info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(tree) = value.get(\"tree\") {\n+ // info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n+ // }\n+ // // Accessing parent commits (merge may be array)\n+ // if let Some(parent) = value.get(\"parents\") {\n+ // if let Value::Array(arr) = parent {\n+ // if let Some(parent) = arr.get(0) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n+ // }\n+ // if let Some(parent) = arr.get(1) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n+ // }\n+ // }\n+ // }\n+ // if let Some(author_name) = value.get(\"author_name\") {\n+ // info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(author_email) = value.get(\"author_email\") {\n+ // info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_name) = value.get(\"committer_name\") {\n+ // info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_email) = value.get(\"committer_email\") {\n+ // info!(\n+ // \"committer_email:\\n{}\",\n+ // committer_email.as_str().unwrap_or(\"\")\n+ // );\n+ // }\n+ //\n+ // //split the commit message into a Vec\n+ // if let Some(message) = value.get(\"message\") {\n+ // let parts = split_json_string(&message, \"\\n\");\n+ // for part in parts {\n+ // info!(\"\\n{}\", part);\n+ // }\n+ // debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Value::Number(time) = &value[\"time\"] {\n+ // info!(\"time:\\n{}\", time);\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\").expect(\"\");\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head().expect(\"\");\n+ // let obj = head\n+ // .resolve()\n+ // .expect(\"\")\n+ // .peel(ObjectType::Commit)\n+ // .expect(\"\");\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit().expect(\"\");\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n+ // //// commit based keys\n+ // //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ // //create nostr client with commit based keys\n+ // //let client = Client::new(keys);\n+ // let client = Client::new(padded_keys.clone());\n+ // global_rt().spawn(async move {\n+ // client\n+ // .add_relay(\"wss://relay.damus.io\")\n+ // .await\n+ // .expect(\"failed to add damus relay\");\n+ // client\n+ // .add_relay(\"wss://nos.lol\")\n+ // .await\n+ // .expect(\"failed to add nos.lol relay\");\n+ // client.connect().await; // connect() likely doesn't return a Result you can match on\n+ // let builder = EventBuilder::text_note(serialized_commit.clone());\n+ // let output = client\n+ // .send_event_builder(builder)\n+ // .await\n+ // .expect(\"589:failed to send event\");\n+ // info!(\"Event ID: {}\", output.id());\n+ // info!(\n+ // \"Event ID BECH32: {}\",\n+ // output\n+ // .id()\n+ // //.public_key()\n+ // .to_bech32()\n+ // .expect(\"failed to convert to bech32\")\n+ // );\n+ // info!(\"Sent to: {:?}\", output.success);\n+ // info!(\"Not sent to: {:?}\", output.failed);\n+ // });\n+ //\n+ // //std::process::exit(0);\n+ //\n+ // //P2P CHAT\n+ // let mut app = ui::App::default();\n+ //\n+ // //TODO\n+ // //for line in TITLE.lines() {\n+ // // app.add_message(\n+ // // Msg::default()\n+ // // .set_content(line.to_string())\n+ // // .set_kind(MsgKind::Raw),\n+ // // );\n+ // //}\n+ //\n+ // use crate::chat::generate_nostr_keys_from_commit_hash;\n+ // let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // info!(\"keys.public_key():\\n{}\", keys.public_key());\n // app.add_message(\n // Msg::default()\n- // .set_content(line.to_string())\n+ // .set_content(keys.public_key().to_string())\n // .set_kind(MsgKind::Raw),\n // );\n- //}\n-\n- use crate::chat::generate_nostr_keys_from_commit_hash;\n- let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- info!(\"keys.public_key():\\n{}\", keys.public_key());\n- app.add_message(\n- Msg::default()\n- .set_content(keys.public_key().to_string())\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"second message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"third message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"fourth message\"))\n- .set_kind(MsgKind::Raw),\n- );\n-\n- let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n- let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n-\n- // let input_loop_fut = input_loop(input_tx);\n- let input_tx_clone = input_tx.clone();\n- app.on_submit(move |m| {\n- debug!(\"sent: {:?}\", m);\n- input_tx_clone.blocking_send(m).unwrap();\n- });\n-\n- let topic = if args.topic.is_some() {\n- args.topic.clone()\n- } else {\n- Some(String::from(commit_id.to_string()))\n- };\n-\n- app.topic = topic.clone().unwrap();\n-\n- let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n-\n- global_rt().spawn(async move {\n- evt_loop(input_rx, peer_tx, topic).await.unwrap();\n- });\n-\n- // recv from peer\n- let mut tui_msg_adder = app.add_msg_fn();\n- global_rt().spawn(async move {\n- while let Some(m) = peer_rx.recv().await {\n- debug!(\"recv: {:?}\", m);\n- tui_msg_adder(m);\n- }\n- });\n-\n- // say hi\n- let input_tx_clone = input_tx.clone();\n- global_rt().spawn(async move {\n- tokio::time::sleep(Duration::from_millis(1000)).await;\n- input_tx_clone\n- .send(Msg::default().set_kind(MsgKind::Join))\n- .await\n- .unwrap();\n- });\n-\n- app.run()?;\n-\n- // say goodbye\n- input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n- std::thread::sleep(Duration::from_millis(500));\n-\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"second message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"third message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"fourth message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ //\n+ // let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n+ // let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n+ //\n+ // // let input_loop_fut = input_loop(input_tx);\n+ // let input_tx_clone = input_tx.clone();\n+ // app.on_submit(move |m| {\n+ // debug!(\"sent: {:?}\", m);\n+ // input_tx_clone.blocking_send(m).unwrap();\n+ // });\n+ //\n+ // let topic = if args.topic.is_some() {\n+ // args.topic.clone()\n+ // } else {\n+ // Some(String::from(commit_id.to_string()))\n+ // };\n+ //\n+ // app.topic = topic.clone().unwrap();\n+ //\n+ // let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n+ //\n+ // global_rt().spawn(async move {\n+ // evt_loop(input_rx, peer_tx, topic).await.unwrap();\n+ // });\n+ //\n+ // // recv from peer\n+ // let mut tui_msg_adder = app.add_msg_fn();\n+ // global_rt().spawn(async move {\n+ // while let Some(m) = peer_rx.recv().await {\n+ // debug!(\"recv: {:?}\", m);\n+ // tui_msg_adder(m);\n+ // }\n+ // });\n+ //\n+ // // say hi\n+ // let input_tx_clone = input_tx.clone();\n+ // global_rt().spawn(async move {\n+ // tokio::time::sleep(Duration::from_millis(1000)).await;\n+ // input_tx_clone\n+ // .send(Msg::default().set_kind(MsgKind::Join))\n+ // .await\n+ // .unwrap();\n+ // });\n+ //\n+ // app.run()?;\n+ //\n+ // // say goodbye\n+ // input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n+ // std::thread::sleep(Duration::from_millis(500));\n+ //\n Ok(())\n }\ndiff --git a/src/lib/sub_commands/fetch.rs b/src/lib/sub_commands/fetch.rs\nindex d6343357..2c05425c 100644\n--- a/src/lib/sub_commands/fetch.rs\n+++ b/src/lib/sub_commands/fetch.rs\n@@ -11,7 +11,7 @@ use crate::{\n repo_ref::get_repo_coordinates,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// address pointer to repo announcement\n #[arg(long, action)]\ndiff --git a/src/lib/sub_commands/login.rs b/src/lib/sub_commands/login.rs\nindex 78ea3a58..176a7043 100644\n--- a/src/lib/sub_commands/login.rs\n+++ b/src/lib/sub_commands/login.rs\n@@ -8,7 +8,7 @@ use crate::{\n login,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// don't fetch user metadata and relay list from relays\n #[arg(long, action)]\n","time":1746136255}

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

{"id":"d685d2683288d3247933e2de0f42f6dc273dd410","tree":"4302487b1f8c4b6048436b70bdcd2a857412aeb5","parents":["34b0e967cfa04f4b42079985ad3f3511e0ac51ef"],"author_name":"randymcmillan","author_email":"randymcmillan@protonmail.com","committer_name":"randymcmillan","committer_email":"randymcmillan@protonmail.com","message":"src/lib/sub_commands/chat.rs:intermediate\n\ndiff --git a/src/lib/cli.rs b/src/lib/cli.rs\nindex c253d97c..a32c01fb 100644\n--- a/src/lib/cli.rs\n+++ b/src/lib/cli.rs\n@@ -44,12 +44,12 @@ pub enum Commands {\n Login(sub_commands::login::SubCommandArgs),\n }\n\n-#[derive(Parser)]\n+#[derive(Parser, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatCli {\n- #[command(subcommand)]\n- pub command: ChatCommands,\n+ // #[command(subcommand)]\n+ // pub command: ChatCommands,\n /// remote signer address\n //#[arg(long, global = true)]\n //pub bunker_uri: Option,\n@@ -67,22 +67,22 @@ pub struct ChatCli {\n //pub disable_cli_spinners: bool,\n }\n\n-#[derive(Subcommand)]\n-pub enum ChatCommands {\n- /// update cache with latest updates from nostr\n- Fetch(sub_commands::fetch::SubCommandArgs),\n- /// signal you are this repo's maintainer accepting proposals via\n- /// nostr\n- Init(sub_commands::init::SubCommandArgs),\n- /// issue commits as a proposal\n- Send(sub_commands::send::SubCommandArgs),\n- /// list proposals; checkout, apply or download selected\n- List,\n- /// send proposal revision\n- Push(sub_commands::push::SubCommandArgs),\n- /// fetch and apply new proposal commits / revisions linked to\n- /// branch\n- Pull,\n- /// run with --nsec flag to change npub\n- Login(sub_commands::login::SubCommandArgs),\n-}\n+//#[derive(Subcommand, Debug)]\n+//pub enum ChatCommands {\n+// /// update cache with latest updates from nostr\n+// Fetch(sub_commands::fetch::SubCommandArgs),\n+// /// signal you are this repo's maintainer accepting proposals via\n+// /// nostr\n+// Init(sub_commands::init::SubCommandArgs),\n+// /// issue commits as a proposal\n+// Send(sub_commands::send::SubCommandArgs),\n+// /// list proposals; checkout, apply or download selected\n+// List,\n+// /// send proposal revision\n+// Push(sub_commands::push::SubCommandArgs),\n+// /// fetch and apply new proposal commits / revisions linked to\n+// /// branch\n+// Pull,\n+// /// run with --nsec flag to change npub\n+// Login(sub_commands::login::SubCommandArgs),\n+//}\ndiff --git a/src/lib/sub_commands/chat.rs b/src/lib/sub_commands/chat.rs\nindex 68edc3d3..bec002f5 100644\n--- a/src/lib/sub_commands/chat.rs\n+++ b/src/lib/sub_commands/chat.rs\n@@ -1,6 +1,6 @@\n #![cfg_attr(not(test), warn(clippy::pedantic))]\n #![cfg_attr(not(test), warn(clippy::expect_used))]\n-use crate::cli::ChatCommands;\n+//use crate::cli::ChatCommands;\n use crate::sub_commands::fetch;\n use crate::sub_commands::init;\n use crate::sub_commands::list;\n@@ -44,12 +44,12 @@ use tracing::{debug, info, Level};\n use tracing_subscriber::util::SubscriberInitExt;\n use tracing_subscriber::{fmt, layer::SubscriberExt, EnvFilter, Registry};\n\n-#[derive(Args)]\n+#[derive(Args, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatSubCommand {\n- #[command(subcommand)]\n- command: ChatCommands,\n+ //#[command(subcommand)]\n+ //command: ChatCommands,\n ///// nsec or hex private key\n #[arg(short, long, global = true)]\n nsec: Option,\n@@ -73,366 +73,367 @@ pub struct ChatSubCommand {\n }\n\n pub async fn chat(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- match &sub_command_args.command {\n- ChatCommands::Login(args) => login::launch(&args).await?,\n- ChatCommands::Init(args) => init::launch(&args).await?,\n- ChatCommands::Send(args) => send::launch(&args, true).await?,\n- ChatCommands::List => list::launch().await?,\n- ChatCommands::Pull => pull::launch().await?,\n- ChatCommands::Push(args) => push::launch(&args).await?,\n- ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n-\t\t_ => return Ok(()),\n-\t}\n- //continue\n-\n- run(sub_command_args);\n+ //match &sub_command_args.command {\n+ //// ChatCommands::Login(args) => login::launch(&args).await?,\n+ //// ChatCommands::Init(args) => init::launch(&args).await?,\n+ //// ChatCommands::Send(args) => send::launch(&args, true).await?,\n+ //// ChatCommands::List => list::launch().await?,\n+ //// ChatCommands::Pull => pull::launch().await?,\n+ //// ChatCommands::Push(args) => push::launch(&args).await?,\n+ //// ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n+ //\t_ => { run(sub_command_args).await? }\n+ //}\n+ run(sub_command_args).await?;\n\n Ok(())\n }\n\n pub async fn run(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- let args = sub_command_args;\n-\n- if let Some(name) = args.name.clone() {\n- use std::env;\n- env::set_var(\"USER\", &name);\n- };\n-\n- let level = if args.debug {\n- Level::DEBUG\n- } else if args.trace {\n- Level::TRACE\n- } else if args.info {\n- Level::INFO\n- } else {\n- Level::WARN\n- };\n-\n- let filter = EnvFilter::default()\n- .add_directive(level.into())\n- .add_directive(\"nostr_sdk=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n- .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n- .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n- .add_directive(\"gnostr::message=off\".parse().unwrap())\n- .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n- .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n- //\n- .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n-\n- let subscriber = Registry::default()\n- .with(fmt::layer().with_writer(std::io::stdout))\n- .with(filter);\n-\n- let _ = subscriber.try_init();\n-\n- if args.debug || args.trace {\n- if args.nsec.clone().is_some() {\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n- print!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- print!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n- }\n- }\n- //parse keys from sha256 hash\n- let empty_hash_keys =\n- Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n-\n- if args.nsec.is_some() {\n- //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n-\n- info!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n-\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\")?;\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head()?;\n- let obj = head.resolve()?.peel(ObjectType::Commit)?;\n-\n- //read top commit\n- let commit = obj.peel_to_commit()?;\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"416:commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id);\n- info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n-\n- //// commit based keys\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n- custom_tags.insert(\n- padded_keys.clone().public_key().to_string(),\n- vec![\"GNOSTR\".to_string()],\n- );\n-\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n- info!(\"467:signed_event:\\n{:?}\", signed_event);\n- });\n-\n- //TODO config metadata\n-\n- //access some git info\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- let binding = serialized_commit.clone();\n- let deserialized_commit = deserialize_commit(&repo, &binding)?;\n- info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n-\n- //access commit summary in the deserialized commit\n- info!(\"481:Original commit ID:\\n{}\", commit_id);\n- info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n-\n- //additional checking\n- if commit.id() != deserialized_commit.id() {\n- debug!(\"Commit IDs do not match!\");\n- } else {\n- debug!(\"Commit IDs match!\");\n- }\n-\n- let value: Value = parse_json(&serialized_commit)?;\n- //info!(\"value:\\n{}\", value);\n-\n- // Accessing object elements.\n- if let Some(id) = value.get(\"id\") {\n- info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n- }\n- if let Some(tree) = value.get(\"tree\") {\n- info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n- }\n- // Accessing parent commits (merge may be array)\n- if let Some(parent) = value.get(\"parents\") {\n- if let Value::Array(arr) = parent {\n- if let Some(parent) = arr.get(0) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n- }\n- if let Some(parent) = arr.get(1) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n- }\n- }\n- }\n- if let Some(author_name) = value.get(\"author_name\") {\n- info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(author_email) = value.get(\"author_email\") {\n- info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_name) = value.get(\"committer_name\") {\n- info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_email) = value.get(\"committer_email\") {\n- info!(\n- \"committer_email:\\n{}\",\n- committer_email.as_str().unwrap_or(\"\")\n- );\n- }\n-\n- //split the commit message into a Vec\n- if let Some(message) = value.get(\"message\") {\n- let parts = split_json_string(&message, \"\\n\");\n- for part in parts {\n- info!(\"\\n{}\", part);\n- }\n- debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n- }\n- if let Value::Number(time) = &value[\"time\"] {\n- info!(\"time:\\n{}\", time);\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\").expect(\"\");\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head().expect(\"\");\n- let obj = head\n- .resolve()\n- .expect(\"\")\n- .peel(ObjectType::Commit)\n- .expect(\"\");\n-\n- //read top commit\n- let commit = obj.peel_to_commit().expect(\"\");\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n- //// commit based keys\n- //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n- //create nostr client with commit based keys\n- //let client = Client::new(keys);\n- let client = Client::new(padded_keys.clone());\n- global_rt().spawn(async move {\n- client\n- .add_relay(\"wss://relay.damus.io\")\n- .await\n- .expect(\"failed to add damus relay\");\n- client\n- .add_relay(\"wss://nos.lol\")\n- .await\n- .expect(\"failed to add nos.lol relay\");\n- client.connect().await; // connect() likely doesn't return a Result you can match on\n- let builder = EventBuilder::text_note(serialized_commit.clone());\n- let output = client\n- .send_event_builder(builder)\n- .await\n- .expect(\"589:failed to send event\");\n- info!(\"Event ID: {}\", output.id());\n- info!(\n- \"Event ID BECH32: {}\",\n- output\n- .id()\n- //.public_key()\n- .to_bech32()\n- .expect(\"failed to convert to bech32\")\n- );\n- info!(\"Sent to: {:?}\", output.success);\n- info!(\"Not sent to: {:?}\", output.failed);\n- });\n-\n- //std::process::exit(0);\n-\n- //P2P CHAT\n- let mut app = ui::App::default();\n-\n- //TODO\n- //for line in TITLE.lines() {\n+ println!(\"{:?}\", &sub_command_args);\n+ let chat = chat;\n+\n+ // let args = sub_command_args;\n+ //\n+ // if let Some(name) = args.name.clone() {\n+ // use std::env;\n+ // env::set_var(\"USER\", &name);\n+ // };\n+ //\n+ // let level = if args.debug {\n+ // Level::DEBUG\n+ // } else if args.trace {\n+ // Level::TRACE\n+ // } else if args.info {\n+ // Level::INFO\n+ // } else {\n+ // Level::WARN\n+ // };\n+ //\n+ // let filter = EnvFilter::default()\n+ // .add_directive(level.into())\n+ // .add_directive(\"nostr_sdk=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n+ // .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::message=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n+ // .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n+ // //\n+ // .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n+ //\n+ // let subscriber = Registry::default()\n+ // .with(fmt::layer().with_writer(std::io::stdout))\n+ // .with(filter);\n+ //\n+ // let _ = subscriber.try_init();\n+ //\n+ // if args.debug || args.trace {\n+ // if args.nsec.clone().is_some() {\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ // debug!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // debug!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ // }\n+ // }\n+ // //parse keys from sha256 hash\n+ // let empty_hash_keys =\n+ // Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // if args.nsec.is_some() {\n+ // //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ //\n+ // info!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ //\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\")?;\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head()?;\n+ // let obj = head.resolve()?.peel(ObjectType::Commit)?;\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit()?;\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"416:commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id);\n+ // info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n+ //\n+ // //// commit based keys\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ // custom_tags.insert(\n+ // padded_keys.clone().public_key().to_string(),\n+ // vec![\"GNOSTR\".to_string()],\n+ // );\n+ //\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n+ // info!(\"467:signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // //TODO config metadata\n+ //\n+ // //access some git info\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // let binding = serialized_commit.clone();\n+ // let deserialized_commit = deserialize_commit(&repo, &binding)?;\n+ // info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n+ //\n+ // //access commit summary in the deserialized commit\n+ // info!(\"481:Original commit ID:\\n{}\", commit_id);\n+ // info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n+ //\n+ // //additional checking\n+ // if commit.id() != deserialized_commit.id() {\n+ // debug!(\"Commit IDs do not match!\");\n+ // } else {\n+ // debug!(\"Commit IDs match!\");\n+ // }\n+ //\n+ // let value: Value = parse_json(&serialized_commit)?;\n+ // //info!(\"value:\\n{}\", value);\n+ //\n+ // // Accessing object elements.\n+ // if let Some(id) = value.get(\"id\") {\n+ // info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(tree) = value.get(\"tree\") {\n+ // info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n+ // }\n+ // // Accessing parent commits (merge may be array)\n+ // if let Some(parent) = value.get(\"parents\") {\n+ // if let Value::Array(arr) = parent {\n+ // if let Some(parent) = arr.get(0) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n+ // }\n+ // if let Some(parent) = arr.get(1) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n+ // }\n+ // }\n+ // }\n+ // if let Some(author_name) = value.get(\"author_name\") {\n+ // info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(author_email) = value.get(\"author_email\") {\n+ // info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_name) = value.get(\"committer_name\") {\n+ // info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_email) = value.get(\"committer_email\") {\n+ // info!(\n+ // \"committer_email:\\n{}\",\n+ // committer_email.as_str().unwrap_or(\"\")\n+ // );\n+ // }\n+ //\n+ // //split the commit message into a Vec\n+ // if let Some(message) = value.get(\"message\") {\n+ // let parts = split_json_string(&message, \"\\n\");\n+ // for part in parts {\n+ // info!(\"\\n{}\", part);\n+ // }\n+ // debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Value::Number(time) = &value[\"time\"] {\n+ // info!(\"time:\\n{}\", time);\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\").expect(\"\");\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head().expect(\"\");\n+ // let obj = head\n+ // .resolve()\n+ // .expect(\"\")\n+ // .peel(ObjectType::Commit)\n+ // .expect(\"\");\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit().expect(\"\");\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n+ // //// commit based keys\n+ // //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ // //create nostr client with commit based keys\n+ // //let client = Client::new(keys);\n+ // let client = Client::new(padded_keys.clone());\n+ // global_rt().spawn(async move {\n+ // client\n+ // .add_relay(\"wss://relay.damus.io\")\n+ // .await\n+ // .expect(\"failed to add damus relay\");\n+ // client\n+ // .add_relay(\"wss://nos.lol\")\n+ // .await\n+ // .expect(\"failed to add nos.lol relay\");\n+ // client.connect().await; // connect() likely doesn't return a Result you can match on\n+ // let builder = EventBuilder::text_note(serialized_commit.clone());\n+ // let output = client\n+ // .send_event_builder(builder)\n+ // .await\n+ // .expect(\"589:failed to send event\");\n+ // info!(\"Event ID: {}\", output.id());\n+ // info!(\n+ // \"Event ID BECH32: {}\",\n+ // output\n+ // .id()\n+ // //.public_key()\n+ // .to_bech32()\n+ // .expect(\"failed to convert to bech32\")\n+ // );\n+ // info!(\"Sent to: {:?}\", output.success);\n+ // info!(\"Not sent to: {:?}\", output.failed);\n+ // });\n+ //\n+ // //std::process::exit(0);\n+ //\n+ // //P2P CHAT\n+ // let mut app = ui::App::default();\n+ //\n+ // //TODO\n+ // //for line in TITLE.lines() {\n+ // // app.add_message(\n+ // // Msg::default()\n+ // // .set_content(line.to_string())\n+ // // .set_kind(MsgKind::Raw),\n+ // // );\n+ // //}\n+ //\n+ // use crate::chat::generate_nostr_keys_from_commit_hash;\n+ // let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // info!(\"keys.public_key():\\n{}\", keys.public_key());\n // app.add_message(\n // Msg::default()\n- // .set_content(line.to_string())\n+ // .set_content(keys.public_key().to_string())\n // .set_kind(MsgKind::Raw),\n // );\n- //}\n-\n- use crate::chat::generate_nostr_keys_from_commit_hash;\n- let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- info!(\"keys.public_key():\\n{}\", keys.public_key());\n- app.add_message(\n- Msg::default()\n- .set_content(keys.public_key().to_string())\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"second message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"third message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"fourth message\"))\n- .set_kind(MsgKind::Raw),\n- );\n-\n- let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n- let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n-\n- // let input_loop_fut = input_loop(input_tx);\n- let input_tx_clone = input_tx.clone();\n- app.on_submit(move |m| {\n- debug!(\"sent: {:?}\", m);\n- input_tx_clone.blocking_send(m).unwrap();\n- });\n-\n- let topic = if args.topic.is_some() {\n- args.topic.clone()\n- } else {\n- Some(String::from(commit_id.to_string()))\n- };\n-\n- app.topic = topic.clone().unwrap();\n-\n- let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n-\n- global_rt().spawn(async move {\n- evt_loop(input_rx, peer_tx, topic).await.unwrap();\n- });\n-\n- // recv from peer\n- let mut tui_msg_adder = app.add_msg_fn();\n- global_rt().spawn(async move {\n- while let Some(m) = peer_rx.recv().await {\n- debug!(\"recv: {:?}\", m);\n- tui_msg_adder(m);\n- }\n- });\n-\n- // say hi\n- let input_tx_clone = input_tx.clone();\n- global_rt().spawn(async move {\n- tokio::time::sleep(Duration::from_millis(1000)).await;\n- input_tx_clone\n- .send(Msg::default().set_kind(MsgKind::Join))\n- .await\n- .unwrap();\n- });\n-\n- app.run()?;\n-\n- // say goodbye\n- input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n- std::thread::sleep(Duration::from_millis(500));\n-\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"second message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"third message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"fourth message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ //\n+ // let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n+ // let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n+ //\n+ // // let input_loop_fut = input_loop(input_tx);\n+ // let input_tx_clone = input_tx.clone();\n+ // app.on_submit(move |m| {\n+ // debug!(\"sent: {:?}\", m);\n+ // input_tx_clone.blocking_send(m).unwrap();\n+ // });\n+ //\n+ // let topic = if args.topic.is_some() {\n+ // args.topic.clone()\n+ // } else {\n+ // Some(String::from(commit_id.to_string()))\n+ // };\n+ //\n+ // app.topic = topic.clone().unwrap();\n+ //\n+ // let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n+ //\n+ // global_rt().spawn(async move {\n+ // evt_loop(input_rx, peer_tx, topic).await.unwrap();\n+ // });\n+ //\n+ // // recv from peer\n+ // let mut tui_msg_adder = app.add_msg_fn();\n+ // global_rt().spawn(async move {\n+ // while let Some(m) = peer_rx.recv().await {\n+ // debug!(\"recv: {:?}\", m);\n+ // tui_msg_adder(m);\n+ // }\n+ // });\n+ //\n+ // // say hi\n+ // let input_tx_clone = input_tx.clone();\n+ // global_rt().spawn(async move {\n+ // tokio::time::sleep(Duration::from_millis(1000)).await;\n+ // input_tx_clone\n+ // .send(Msg::default().set_kind(MsgKind::Join))\n+ // .await\n+ // .unwrap();\n+ // });\n+ //\n+ // app.run()?;\n+ //\n+ // // say goodbye\n+ // input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n+ // std::thread::sleep(Duration::from_millis(500));\n+ //\n Ok(())\n }\ndiff --git a/src/lib/sub_commands/fetch.rs b/src/lib/sub_commands/fetch.rs\nindex d6343357..2c05425c 100644\n--- a/src/lib/sub_commands/fetch.rs\n+++ b/src/lib/sub_commands/fetch.rs\n@@ -11,7 +11,7 @@ use crate::{\n repo_ref::get_repo_coordinates,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// address pointer to repo announcement\n #[arg(long, action)]\ndiff --git a/src/lib/sub_commands/login.rs b/src/lib/sub_commands/login.rs\nindex 78ea3a58..176a7043 100644\n--- a/src/lib/sub_commands/login.rs\n+++ b/src/lib/sub_commands/login.rs\n@@ -8,7 +8,7 @@ use crate::{\n login,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// don't fetch user metadata and relay list from relays\n #[arg(long, action)]\n","time":1746136255}

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

{"id":"d685d2683288d3247933e2de0f42f6dc273dd410","tree":"4302487b1f8c4b6048436b70bdcd2a857412aeb5","parents":["34b0e967cfa04f4b42079985ad3f3511e0ac51ef"],"author_name":"randymcmillan","author_email":"randymcmillan@protonmail.com","committer_name":"randymcmillan","committer_email":"randymcmillan@protonmail.com","message":"src/lib/sub_commands/chat.rs:intermediate\n\ndiff --git a/src/lib/cli.rs b/src/lib/cli.rs\nindex c253d97c..a32c01fb 100644\n--- a/src/lib/cli.rs\n+++ b/src/lib/cli.rs\n@@ -44,12 +44,12 @@ pub enum Commands {\n Login(sub_commands::login::SubCommandArgs),\n }\n\n-#[derive(Parser)]\n+#[derive(Parser, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatCli {\n- #[command(subcommand)]\n- pub command: ChatCommands,\n+ // #[command(subcommand)]\n+ // pub command: ChatCommands,\n /// remote signer address\n //#[arg(long, global = true)]\n //pub bunker_uri: Option,\n@@ -67,22 +67,22 @@ pub struct ChatCli {\n //pub disable_cli_spinners: bool,\n }\n\n-#[derive(Subcommand)]\n-pub enum ChatCommands {\n- /// update cache with latest updates from nostr\n- Fetch(sub_commands::fetch::SubCommandArgs),\n- /// signal you are this repo's maintainer accepting proposals via\n- /// nostr\n- Init(sub_commands::init::SubCommandArgs),\n- /// issue commits as a proposal\n- Send(sub_commands::send::SubCommandArgs),\n- /// list proposals; checkout, apply or download selected\n- List,\n- /// send proposal revision\n- Push(sub_commands::push::SubCommandArgs),\n- /// fetch and apply new proposal commits / revisions linked to\n- /// branch\n- Pull,\n- /// run with --nsec flag to change npub\n- Login(sub_commands::login::SubCommandArgs),\n-}\n+//#[derive(Subcommand, Debug)]\n+//pub enum ChatCommands {\n+// /// update cache with latest updates from nostr\n+// Fetch(sub_commands::fetch::SubCommandArgs),\n+// /// signal you are this repo's maintainer accepting proposals via\n+// /// nostr\n+// Init(sub_commands::init::SubCommandArgs),\n+// /// issue commits as a proposal\n+// Send(sub_commands::send::SubCommandArgs),\n+// /// list proposals; checkout, apply or download selected\n+// List,\n+// /// send proposal revision\n+// Push(sub_commands::push::SubCommandArgs),\n+// /// fetch and apply new proposal commits / revisions linked to\n+// /// branch\n+// Pull,\n+// /// run with --nsec flag to change npub\n+// Login(sub_commands::login::SubCommandArgs),\n+//}\ndiff --git a/src/lib/sub_commands/chat.rs b/src/lib/sub_commands/chat.rs\nindex 68edc3d3..bec002f5 100644\n--- a/src/lib/sub_commands/chat.rs\n+++ b/src/lib/sub_commands/chat.rs\n@@ -1,6 +1,6 @@\n #![cfg_attr(not(test), warn(clippy::pedantic))]\n #![cfg_attr(not(test), warn(clippy::expect_used))]\n-use crate::cli::ChatCommands;\n+//use crate::cli::ChatCommands;\n use crate::sub_commands::fetch;\n use crate::sub_commands::init;\n use crate::sub_commands::list;\n@@ -44,12 +44,12 @@ use tracing::{debug, info, Level};\n use tracing_subscriber::util::SubscriberInitExt;\n use tracing_subscriber::{fmt, layer::SubscriberExt, EnvFilter, Registry};\n\n-#[derive(Args)]\n+#[derive(Args, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatSubCommand {\n- #[command(subcommand)]\n- command: ChatCommands,\n+ //#[command(subcommand)]\n+ //command: ChatCommands,\n ///// nsec or hex private key\n #[arg(short, long, global = true)]\n nsec: Option,\n@@ -73,366 +73,367 @@ pub struct ChatSubCommand {\n }\n\n pub async fn chat(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- match &sub_command_args.command {\n- ChatCommands::Login(args) => login::launch(&args).await?,\n- ChatCommands::Init(args) => init::launch(&args).await?,\n- ChatCommands::Send(args) => send::launch(&args, true).await?,\n- ChatCommands::List => list::launch().await?,\n- ChatCommands::Pull => pull::launch().await?,\n- ChatCommands::Push(args) => push::launch(&args).await?,\n- ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n-\t\t_ => return Ok(()),\n-\t}\n- //continue\n-\n- run(sub_command_args);\n+ //match &sub_command_args.command {\n+ //// ChatCommands::Login(args) => login::launch(&args).await?,\n+ //// ChatCommands::Init(args) => init::launch(&args).await?,\n+ //// ChatCommands::Send(args) => send::launch(&args, true).await?,\n+ //// ChatCommands::List => list::launch().await?,\n+ //// ChatCommands::Pull => pull::launch().await?,\n+ //// ChatCommands::Push(args) => push::launch(&args).await?,\n+ //// ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n+ //\t_ => { run(sub_command_args).await? }\n+ //}\n+ run(sub_command_args).await?;\n\n Ok(())\n }\n\n pub async fn run(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- let args = sub_command_args;\n-\n- if let Some(name) = args.name.clone() {\n- use std::env;\n- env::set_var(\"USER\", &name);\n- };\n-\n- let level = if args.debug {\n- Level::DEBUG\n- } else if args.trace {\n- Level::TRACE\n- } else if args.info {\n- Level::INFO\n- } else {\n- Level::WARN\n- };\n-\n- let filter = EnvFilter::default()\n- .add_directive(level.into())\n- .add_directive(\"nostr_sdk=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n- .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n- .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n- .add_directive(\"gnostr::message=off\".parse().unwrap())\n- .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n- .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n- //\n- .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n-\n- let subscriber = Registry::default()\n- .with(fmt::layer().with_writer(std::io::stdout))\n- .with(filter);\n-\n- let _ = subscriber.try_init();\n-\n- if args.debug || args.trace {\n- if args.nsec.clone().is_some() {\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n- print!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- print!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n- }\n- }\n- //parse keys from sha256 hash\n- let empty_hash_keys =\n- Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n-\n- if args.nsec.is_some() {\n- //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n-\n- info!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n-\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\")?;\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head()?;\n- let obj = head.resolve()?.peel(ObjectType::Commit)?;\n-\n- //read top commit\n- let commit = obj.peel_to_commit()?;\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"416:commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id);\n- info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n-\n- //// commit based keys\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n- custom_tags.insert(\n- padded_keys.clone().public_key().to_string(),\n- vec![\"GNOSTR\".to_string()],\n- );\n-\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n- info!(\"467:signed_event:\\n{:?}\", signed_event);\n- });\n-\n- //TODO config metadata\n-\n- //access some git info\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- let binding = serialized_commit.clone();\n- let deserialized_commit = deserialize_commit(&repo, &binding)?;\n- info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n-\n- //access commit summary in the deserialized commit\n- info!(\"481:Original commit ID:\\n{}\", commit_id);\n- info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n-\n- //additional checking\n- if commit.id() != deserialized_commit.id() {\n- debug!(\"Commit IDs do not match!\");\n- } else {\n- debug!(\"Commit IDs match!\");\n- }\n-\n- let value: Value = parse_json(&serialized_commit)?;\n- //info!(\"value:\\n{}\", value);\n-\n- // Accessing object elements.\n- if let Some(id) = value.get(\"id\") {\n- info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n- }\n- if let Some(tree) = value.get(\"tree\") {\n- info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n- }\n- // Accessing parent commits (merge may be array)\n- if let Some(parent) = value.get(\"parents\") {\n- if let Value::Array(arr) = parent {\n- if let Some(parent) = arr.get(0) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n- }\n- if let Some(parent) = arr.get(1) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n- }\n- }\n- }\n- if let Some(author_name) = value.get(\"author_name\") {\n- info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(author_email) = value.get(\"author_email\") {\n- info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_name) = value.get(\"committer_name\") {\n- info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_email) = value.get(\"committer_email\") {\n- info!(\n- \"committer_email:\\n{}\",\n- committer_email.as_str().unwrap_or(\"\")\n- );\n- }\n-\n- //split the commit message into a Vec\n- if let Some(message) = value.get(\"message\") {\n- let parts = split_json_string(&message, \"\\n\");\n- for part in parts {\n- info!(\"\\n{}\", part);\n- }\n- debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n- }\n- if let Value::Number(time) = &value[\"time\"] {\n- info!(\"time:\\n{}\", time);\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\").expect(\"\");\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head().expect(\"\");\n- let obj = head\n- .resolve()\n- .expect(\"\")\n- .peel(ObjectType::Commit)\n- .expect(\"\");\n-\n- //read top commit\n- let commit = obj.peel_to_commit().expect(\"\");\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n- //// commit based keys\n- //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n- //create nostr client with commit based keys\n- //let client = Client::new(keys);\n- let client = Client::new(padded_keys.clone());\n- global_rt().spawn(async move {\n- client\n- .add_relay(\"wss://relay.damus.io\")\n- .await\n- .expect(\"failed to add damus relay\");\n- client\n- .add_relay(\"wss://nos.lol\")\n- .await\n- .expect(\"failed to add nos.lol relay\");\n- client.connect().await; // connect() likely doesn't return a Result you can match on\n- let builder = EventBuilder::text_note(serialized_commit.clone());\n- let output = client\n- .send_event_builder(builder)\n- .await\n- .expect(\"589:failed to send event\");\n- info!(\"Event ID: {}\", output.id());\n- info!(\n- \"Event ID BECH32: {}\",\n- output\n- .id()\n- //.public_key()\n- .to_bech32()\n- .expect(\"failed to convert to bech32\")\n- );\n- info!(\"Sent to: {:?}\", output.success);\n- info!(\"Not sent to: {:?}\", output.failed);\n- });\n-\n- //std::process::exit(0);\n-\n- //P2P CHAT\n- let mut app = ui::App::default();\n-\n- //TODO\n- //for line in TITLE.lines() {\n+ println!(\"{:?}\", &sub_command_args);\n+ let chat = chat;\n+\n+ // let args = sub_command_args;\n+ //\n+ // if let Some(name) = args.name.clone() {\n+ // use std::env;\n+ // env::set_var(\"USER\", &name);\n+ // };\n+ //\n+ // let level = if args.debug {\n+ // Level::DEBUG\n+ // } else if args.trace {\n+ // Level::TRACE\n+ // } else if args.info {\n+ // Level::INFO\n+ // } else {\n+ // Level::WARN\n+ // };\n+ //\n+ // let filter = EnvFilter::default()\n+ // .add_directive(level.into())\n+ // .add_directive(\"nostr_sdk=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n+ // .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::message=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n+ // .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n+ // //\n+ // .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n+ //\n+ // let subscriber = Registry::default()\n+ // .with(fmt::layer().with_writer(std::io::stdout))\n+ // .with(filter);\n+ //\n+ // let _ = subscriber.try_init();\n+ //\n+ // if args.debug || args.trace {\n+ // if args.nsec.clone().is_some() {\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ // debug!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // debug!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ // }\n+ // }\n+ // //parse keys from sha256 hash\n+ // let empty_hash_keys =\n+ // Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // if args.nsec.is_some() {\n+ // //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ //\n+ // info!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ //\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\")?;\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head()?;\n+ // let obj = head.resolve()?.peel(ObjectType::Commit)?;\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit()?;\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"416:commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id);\n+ // info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n+ //\n+ // //// commit based keys\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ // custom_tags.insert(\n+ // padded_keys.clone().public_key().to_string(),\n+ // vec![\"GNOSTR\".to_string()],\n+ // );\n+ //\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n+ // info!(\"467:signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // //TODO config metadata\n+ //\n+ // //access some git info\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // let binding = serialized_commit.clone();\n+ // let deserialized_commit = deserialize_commit(&repo, &binding)?;\n+ // info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n+ //\n+ // //access commit summary in the deserialized commit\n+ // info!(\"481:Original commit ID:\\n{}\", commit_id);\n+ // info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n+ //\n+ // //additional checking\n+ // if commit.id() != deserialized_commit.id() {\n+ // debug!(\"Commit IDs do not match!\");\n+ // } else {\n+ // debug!(\"Commit IDs match!\");\n+ // }\n+ //\n+ // let value: Value = parse_json(&serialized_commit)?;\n+ // //info!(\"value:\\n{}\", value);\n+ //\n+ // // Accessing object elements.\n+ // if let Some(id) = value.get(\"id\") {\n+ // info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(tree) = value.get(\"tree\") {\n+ // info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n+ // }\n+ // // Accessing parent commits (merge may be array)\n+ // if let Some(parent) = value.get(\"parents\") {\n+ // if let Value::Array(arr) = parent {\n+ // if let Some(parent) = arr.get(0) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n+ // }\n+ // if let Some(parent) = arr.get(1) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n+ // }\n+ // }\n+ // }\n+ // if let Some(author_name) = value.get(\"author_name\") {\n+ // info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(author_email) = value.get(\"author_email\") {\n+ // info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_name) = value.get(\"committer_name\") {\n+ // info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_email) = value.get(\"committer_email\") {\n+ // info!(\n+ // \"committer_email:\\n{}\",\n+ // committer_email.as_str().unwrap_or(\"\")\n+ // );\n+ // }\n+ //\n+ // //split the commit message into a Vec\n+ // if let Some(message) = value.get(\"message\") {\n+ // let parts = split_json_string(&message, \"\\n\");\n+ // for part in parts {\n+ // info!(\"\\n{}\", part);\n+ // }\n+ // debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Value::Number(time) = &value[\"time\"] {\n+ // info!(\"time:\\n{}\", time);\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\").expect(\"\");\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head().expect(\"\");\n+ // let obj = head\n+ // .resolve()\n+ // .expect(\"\")\n+ // .peel(ObjectType::Commit)\n+ // .expect(\"\");\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit().expect(\"\");\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n+ // //// commit based keys\n+ // //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ // //create nostr client with commit based keys\n+ // //let client = Client::new(keys);\n+ // let client = Client::new(padded_keys.clone());\n+ // global_rt().spawn(async move {\n+ // client\n+ // .add_relay(\"wss://relay.damus.io\")\n+ // .await\n+ // .expect(\"failed to add damus relay\");\n+ // client\n+ // .add_relay(\"wss://nos.lol\")\n+ // .await\n+ // .expect(\"failed to add nos.lol relay\");\n+ // client.connect().await; // connect() likely doesn't return a Result you can match on\n+ // let builder = EventBuilder::text_note(serialized_commit.clone());\n+ // let output = client\n+ // .send_event_builder(builder)\n+ // .await\n+ // .expect(\"589:failed to send event\");\n+ // info!(\"Event ID: {}\", output.id());\n+ // info!(\n+ // \"Event ID BECH32: {}\",\n+ // output\n+ // .id()\n+ // //.public_key()\n+ // .to_bech32()\n+ // .expect(\"failed to convert to bech32\")\n+ // );\n+ // info!(\"Sent to: {:?}\", output.success);\n+ // info!(\"Not sent to: {:?}\", output.failed);\n+ // });\n+ //\n+ // //std::process::exit(0);\n+ //\n+ // //P2P CHAT\n+ // let mut app = ui::App::default();\n+ //\n+ // //TODO\n+ // //for line in TITLE.lines() {\n+ // // app.add_message(\n+ // // Msg::default()\n+ // // .set_content(line.to_string())\n+ // // .set_kind(MsgKind::Raw),\n+ // // );\n+ // //}\n+ //\n+ // use crate::chat::generate_nostr_keys_from_commit_hash;\n+ // let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // info!(\"keys.public_key():\\n{}\", keys.public_key());\n // app.add_message(\n // Msg::default()\n- // .set_content(line.to_string())\n+ // .set_content(keys.public_key().to_string())\n // .set_kind(MsgKind::Raw),\n // );\n- //}\n-\n- use crate::chat::generate_nostr_keys_from_commit_hash;\n- let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- info!(\"keys.public_key():\\n{}\", keys.public_key());\n- app.add_message(\n- Msg::default()\n- .set_content(keys.public_key().to_string())\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"second message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"third message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"fourth message\"))\n- .set_kind(MsgKind::Raw),\n- );\n-\n- let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n- let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n-\n- // let input_loop_fut = input_loop(input_tx);\n- let input_tx_clone = input_tx.clone();\n- app.on_submit(move |m| {\n- debug!(\"sent: {:?}\", m);\n- input_tx_clone.blocking_send(m).unwrap();\n- });\n-\n- let topic = if args.topic.is_some() {\n- args.topic.clone()\n- } else {\n- Some(String::from(commit_id.to_string()))\n- };\n-\n- app.topic = topic.clone().unwrap();\n-\n- let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n-\n- global_rt().spawn(async move {\n- evt_loop(input_rx, peer_tx, topic).await.unwrap();\n- });\n-\n- // recv from peer\n- let mut tui_msg_adder = app.add_msg_fn();\n- global_rt().spawn(async move {\n- while let Some(m) = peer_rx.recv().await {\n- debug!(\"recv: {:?}\", m);\n- tui_msg_adder(m);\n- }\n- });\n-\n- // say hi\n- let input_tx_clone = input_tx.clone();\n- global_rt().spawn(async move {\n- tokio::time::sleep(Duration::from_millis(1000)).await;\n- input_tx_clone\n- .send(Msg::default().set_kind(MsgKind::Join))\n- .await\n- .unwrap();\n- });\n-\n- app.run()?;\n-\n- // say goodbye\n- input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n- std::thread::sleep(Duration::from_millis(500));\n-\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"second message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"third message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"fourth message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ //\n+ // let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n+ // let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n+ //\n+ // // let input_loop_fut = input_loop(input_tx);\n+ // let input_tx_clone = input_tx.clone();\n+ // app.on_submit(move |m| {\n+ // debug!(\"sent: {:?}\", m);\n+ // input_tx_clone.blocking_send(m).unwrap();\n+ // });\n+ //\n+ // let topic = if args.topic.is_some() {\n+ // args.topic.clone()\n+ // } else {\n+ // Some(String::from(commit_id.to_string()))\n+ // };\n+ //\n+ // app.topic = topic.clone().unwrap();\n+ //\n+ // let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n+ //\n+ // global_rt().spawn(async move {\n+ // evt_loop(input_rx, peer_tx, topic).await.unwrap();\n+ // });\n+ //\n+ // // recv from peer\n+ // let mut tui_msg_adder = app.add_msg_fn();\n+ // global_rt().spawn(async move {\n+ // while let Some(m) = peer_rx.recv().await {\n+ // debug!(\"recv: {:?}\", m);\n+ // tui_msg_adder(m);\n+ // }\n+ // });\n+ //\n+ // // say hi\n+ // let input_tx_clone = input_tx.clone();\n+ // global_rt().spawn(async move {\n+ // tokio::time::sleep(Duration::from_millis(1000)).await;\n+ // input_tx_clone\n+ // .send(Msg::default().set_kind(MsgKind::Join))\n+ // .await\n+ // .unwrap();\n+ // });\n+ //\n+ // app.run()?;\n+ //\n+ // // say goodbye\n+ // input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n+ // std::thread::sleep(Duration::from_millis(500));\n+ //\n Ok(())\n }\ndiff --git a/src/lib/sub_commands/fetch.rs b/src/lib/sub_commands/fetch.rs\nindex d6343357..2c05425c 100644\n--- a/src/lib/sub_commands/fetch.rs\n+++ b/src/lib/sub_commands/fetch.rs\n@@ -11,7 +11,7 @@ use crate::{\n repo_ref::get_repo_coordinates,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// address pointer to repo announcement\n #[arg(long, action)]\ndiff --git a/src/lib/sub_commands/login.rs b/src/lib/sub_commands/login.rs\nindex 78ea3a58..176a7043 100644\n--- a/src/lib/sub_commands/login.rs\n+++ b/src/lib/sub_commands/login.rs\n@@ -8,7 +8,7 @@ use crate::{\n login,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// don't fetch user metadata and relay list from relays\n #[arg(long, action)]\n","time":1746136255}

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

{"id":"d685d2683288d3247933e2de0f42f6dc273dd410","tree":"4302487b1f8c4b6048436b70bdcd2a857412aeb5","parents":["34b0e967cfa04f4b42079985ad3f3511e0ac51ef"],"author_name":"randymcmillan","author_email":"randymcmillan@protonmail.com","committer_name":"randymcmillan","committer_email":"randymcmillan@protonmail.com","message":"src/lib/sub_commands/chat.rs:intermediate\n\ndiff --git a/src/lib/cli.rs b/src/lib/cli.rs\nindex c253d97c..a32c01fb 100644\n--- a/src/lib/cli.rs\n+++ b/src/lib/cli.rs\n@@ -44,12 +44,12 @@ pub enum Commands {\n Login(sub_commands::login::SubCommandArgs),\n }\n\n-#[derive(Parser)]\n+#[derive(Parser, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatCli {\n- #[command(subcommand)]\n- pub command: ChatCommands,\n+ // #[command(subcommand)]\n+ // pub command: ChatCommands,\n /// remote signer address\n //#[arg(long, global = true)]\n //pub bunker_uri: Option,\n@@ -67,22 +67,22 @@ pub struct ChatCli {\n //pub disable_cli_spinners: bool,\n }\n\n-#[derive(Subcommand)]\n-pub enum ChatCommands {\n- /// update cache with latest updates from nostr\n- Fetch(sub_commands::fetch::SubCommandArgs),\n- /// signal you are this repo's maintainer accepting proposals via\n- /// nostr\n- Init(sub_commands::init::SubCommandArgs),\n- /// issue commits as a proposal\n- Send(sub_commands::send::SubCommandArgs),\n- /// list proposals; checkout, apply or download selected\n- List,\n- /// send proposal revision\n- Push(sub_commands::push::SubCommandArgs),\n- /// fetch and apply new proposal commits / revisions linked to\n- /// branch\n- Pull,\n- /// run with --nsec flag to change npub\n- Login(sub_commands::login::SubCommandArgs),\n-}\n+//#[derive(Subcommand, Debug)]\n+//pub enum ChatCommands {\n+// /// update cache with latest updates from nostr\n+// Fetch(sub_commands::fetch::SubCommandArgs),\n+// /// signal you are this repo's maintainer accepting proposals via\n+// /// nostr\n+// Init(sub_commands::init::SubCommandArgs),\n+// /// issue commits as a proposal\n+// Send(sub_commands::send::SubCommandArgs),\n+// /// list proposals; checkout, apply or download selected\n+// List,\n+// /// send proposal revision\n+// Push(sub_commands::push::SubCommandArgs),\n+// /// fetch and apply new proposal commits / revisions linked to\n+// /// branch\n+// Pull,\n+// /// run with --nsec flag to change npub\n+// Login(sub_commands::login::SubCommandArgs),\n+//}\ndiff --git a/src/lib/sub_commands/chat.rs b/src/lib/sub_commands/chat.rs\nindex 68edc3d3..bec002f5 100644\n--- a/src/lib/sub_commands/chat.rs\n+++ b/src/lib/sub_commands/chat.rs\n@@ -1,6 +1,6 @@\n #![cfg_attr(not(test), warn(clippy::pedantic))]\n #![cfg_attr(not(test), warn(clippy::expect_used))]\n-use crate::cli::ChatCommands;\n+//use crate::cli::ChatCommands;\n use crate::sub_commands::fetch;\n use crate::sub_commands::init;\n use crate::sub_commands::list;\n@@ -44,12 +44,12 @@ use tracing::{debug, info, Level};\n use tracing_subscriber::util::SubscriberInitExt;\n use tracing_subscriber::{fmt, layer::SubscriberExt, EnvFilter, Registry};\n\n-#[derive(Args)]\n+#[derive(Args, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatSubCommand {\n- #[command(subcommand)]\n- command: ChatCommands,\n+ //#[command(subcommand)]\n+ //command: ChatCommands,\n ///// nsec or hex private key\n #[arg(short, long, global = true)]\n nsec: Option,\n@@ -73,366 +73,367 @@ pub struct ChatSubCommand {\n }\n\n pub async fn chat(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- match &sub_command_args.command {\n- ChatCommands::Login(args) => login::launch(&args).await?,\n- ChatCommands::Init(args) => init::launch(&args).await?,\n- ChatCommands::Send(args) => send::launch(&args, true).await?,\n- ChatCommands::List => list::launch().await?,\n- ChatCommands::Pull => pull::launch().await?,\n- ChatCommands::Push(args) => push::launch(&args).await?,\n- ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n-\t\t_ => return Ok(()),\n-\t}\n- //continue\n-\n- run(sub_command_args);\n+ //match &sub_command_args.command {\n+ //// ChatCommands::Login(args) => login::launch(&args).await?,\n+ //// ChatCommands::Init(args) => init::launch(&args).await?,\n+ //// ChatCommands::Send(args) => send::launch(&args, true).await?,\n+ //// ChatCommands::List => list::launch().await?,\n+ //// ChatCommands::Pull => pull::launch().await?,\n+ //// ChatCommands::Push(args) => push::launch(&args).await?,\n+ //// ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n+ //\t_ => { run(sub_command_args).await? }\n+ //}\n+ run(sub_command_args).await?;\n\n Ok(())\n }\n\n pub async fn run(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- let args = sub_command_args;\n-\n- if let Some(name) = args.name.clone() {\n- use std::env;\n- env::set_var(\"USER\", &name);\n- };\n-\n- let level = if args.debug {\n- Level::DEBUG\n- } else if args.trace {\n- Level::TRACE\n- } else if args.info {\n- Level::INFO\n- } else {\n- Level::WARN\n- };\n-\n- let filter = EnvFilter::default()\n- .add_directive(level.into())\n- .add_directive(\"nostr_sdk=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n- .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n- .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n- .add_directive(\"gnostr::message=off\".parse().unwrap())\n- .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n- .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n- //\n- .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n-\n- let subscriber = Registry::default()\n- .with(fmt::layer().with_writer(std::io::stdout))\n- .with(filter);\n-\n- let _ = subscriber.try_init();\n-\n- if args.debug || args.trace {\n- if args.nsec.clone().is_some() {\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n- print!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- print!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n- }\n- }\n- //parse keys from sha256 hash\n- let empty_hash_keys =\n- Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n-\n- if args.nsec.is_some() {\n- //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n-\n- info!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n-\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\")?;\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head()?;\n- let obj = head.resolve()?.peel(ObjectType::Commit)?;\n-\n- //read top commit\n- let commit = obj.peel_to_commit()?;\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"416:commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id);\n- info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n-\n- //// commit based keys\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n- custom_tags.insert(\n- padded_keys.clone().public_key().to_string(),\n- vec![\"GNOSTR\".to_string()],\n- );\n-\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n- info!(\"467:signed_event:\\n{:?}\", signed_event);\n- });\n-\n- //TODO config metadata\n-\n- //access some git info\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- let binding = serialized_commit.clone();\n- let deserialized_commit = deserialize_commit(&repo, &binding)?;\n- info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n-\n- //access commit summary in the deserialized commit\n- info!(\"481:Original commit ID:\\n{}\", commit_id);\n- info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n-\n- //additional checking\n- if commit.id() != deserialized_commit.id() {\n- debug!(\"Commit IDs do not match!\");\n- } else {\n- debug!(\"Commit IDs match!\");\n- }\n-\n- let value: Value = parse_json(&serialized_commit)?;\n- //info!(\"value:\\n{}\", value);\n-\n- // Accessing object elements.\n- if let Some(id) = value.get(\"id\") {\n- info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n- }\n- if let Some(tree) = value.get(\"tree\") {\n- info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n- }\n- // Accessing parent commits (merge may be array)\n- if let Some(parent) = value.get(\"parents\") {\n- if let Value::Array(arr) = parent {\n- if let Some(parent) = arr.get(0) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n- }\n- if let Some(parent) = arr.get(1) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n- }\n- }\n- }\n- if let Some(author_name) = value.get(\"author_name\") {\n- info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(author_email) = value.get(\"author_email\") {\n- info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_name) = value.get(\"committer_name\") {\n- info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_email) = value.get(\"committer_email\") {\n- info!(\n- \"committer_email:\\n{}\",\n- committer_email.as_str().unwrap_or(\"\")\n- );\n- }\n-\n- //split the commit message into a Vec\n- if let Some(message) = value.get(\"message\") {\n- let parts = split_json_string(&message, \"\\n\");\n- for part in parts {\n- info!(\"\\n{}\", part);\n- }\n- debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n- }\n- if let Value::Number(time) = &value[\"time\"] {\n- info!(\"time:\\n{}\", time);\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\").expect(\"\");\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head().expect(\"\");\n- let obj = head\n- .resolve()\n- .expect(\"\")\n- .peel(ObjectType::Commit)\n- .expect(\"\");\n-\n- //read top commit\n- let commit = obj.peel_to_commit().expect(\"\");\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n- //// commit based keys\n- //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n- //create nostr client with commit based keys\n- //let client = Client::new(keys);\n- let client = Client::new(padded_keys.clone());\n- global_rt().spawn(async move {\n- client\n- .add_relay(\"wss://relay.damus.io\")\n- .await\n- .expect(\"failed to add damus relay\");\n- client\n- .add_relay(\"wss://nos.lol\")\n- .await\n- .expect(\"failed to add nos.lol relay\");\n- client.connect().await; // connect() likely doesn't return a Result you can match on\n- let builder = EventBuilder::text_note(serialized_commit.clone());\n- let output = client\n- .send_event_builder(builder)\n- .await\n- .expect(\"589:failed to send event\");\n- info!(\"Event ID: {}\", output.id());\n- info!(\n- \"Event ID BECH32: {}\",\n- output\n- .id()\n- //.public_key()\n- .to_bech32()\n- .expect(\"failed to convert to bech32\")\n- );\n- info!(\"Sent to: {:?}\", output.success);\n- info!(\"Not sent to: {:?}\", output.failed);\n- });\n-\n- //std::process::exit(0);\n-\n- //P2P CHAT\n- let mut app = ui::App::default();\n-\n- //TODO\n- //for line in TITLE.lines() {\n+ println!(\"{:?}\", &sub_command_args);\n+ let chat = chat;\n+\n+ // let args = sub_command_args;\n+ //\n+ // if let Some(name) = args.name.clone() {\n+ // use std::env;\n+ // env::set_var(\"USER\", &name);\n+ // };\n+ //\n+ // let level = if args.debug {\n+ // Level::DEBUG\n+ // } else if args.trace {\n+ // Level::TRACE\n+ // } else if args.info {\n+ // Level::INFO\n+ // } else {\n+ // Level::WARN\n+ // };\n+ //\n+ // let filter = EnvFilter::default()\n+ // .add_directive(level.into())\n+ // .add_directive(\"nostr_sdk=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n+ // .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::message=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n+ // .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n+ // //\n+ // .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n+ //\n+ // let subscriber = Registry::default()\n+ // .with(fmt::layer().with_writer(std::io::stdout))\n+ // .with(filter);\n+ //\n+ // let _ = subscriber.try_init();\n+ //\n+ // if args.debug || args.trace {\n+ // if args.nsec.clone().is_some() {\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ // debug!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // debug!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ // }\n+ // }\n+ // //parse keys from sha256 hash\n+ // let empty_hash_keys =\n+ // Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // if args.nsec.is_some() {\n+ // //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ //\n+ // info!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ //\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\")?;\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head()?;\n+ // let obj = head.resolve()?.peel(ObjectType::Commit)?;\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit()?;\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"416:commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id);\n+ // info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n+ //\n+ // //// commit based keys\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ // custom_tags.insert(\n+ // padded_keys.clone().public_key().to_string(),\n+ // vec![\"GNOSTR\".to_string()],\n+ // );\n+ //\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n+ // info!(\"467:signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // //TODO config metadata\n+ //\n+ // //access some git info\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // let binding = serialized_commit.clone();\n+ // let deserialized_commit = deserialize_commit(&repo, &binding)?;\n+ // info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n+ //\n+ // //access commit summary in the deserialized commit\n+ // info!(\"481:Original commit ID:\\n{}\", commit_id);\n+ // info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n+ //\n+ // //additional checking\n+ // if commit.id() != deserialized_commit.id() {\n+ // debug!(\"Commit IDs do not match!\");\n+ // } else {\n+ // debug!(\"Commit IDs match!\");\n+ // }\n+ //\n+ // let value: Value = parse_json(&serialized_commit)?;\n+ // //info!(\"value:\\n{}\", value);\n+ //\n+ // // Accessing object elements.\n+ // if let Some(id) = value.get(\"id\") {\n+ // info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(tree) = value.get(\"tree\") {\n+ // info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n+ // }\n+ // // Accessing parent commits (merge may be array)\n+ // if let Some(parent) = value.get(\"parents\") {\n+ // if let Value::Array(arr) = parent {\n+ // if let Some(parent) = arr.get(0) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n+ // }\n+ // if let Some(parent) = arr.get(1) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n+ // }\n+ // }\n+ // }\n+ // if let Some(author_name) = value.get(\"author_name\") {\n+ // info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(author_email) = value.get(\"author_email\") {\n+ // info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_name) = value.get(\"committer_name\") {\n+ // info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_email) = value.get(\"committer_email\") {\n+ // info!(\n+ // \"committer_email:\\n{}\",\n+ // committer_email.as_str().unwrap_or(\"\")\n+ // );\n+ // }\n+ //\n+ // //split the commit message into a Vec\n+ // if let Some(message) = value.get(\"message\") {\n+ // let parts = split_json_string(&message, \"\\n\");\n+ // for part in parts {\n+ // info!(\"\\n{}\", part);\n+ // }\n+ // debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Value::Number(time) = &value[\"time\"] {\n+ // info!(\"time:\\n{}\", time);\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\").expect(\"\");\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head().expect(\"\");\n+ // let obj = head\n+ // .resolve()\n+ // .expect(\"\")\n+ // .peel(ObjectType::Commit)\n+ // .expect(\"\");\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit().expect(\"\");\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n+ // //// commit based keys\n+ // //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ // //create nostr client with commit based keys\n+ // //let client = Client::new(keys);\n+ // let client = Client::new(padded_keys.clone());\n+ // global_rt().spawn(async move {\n+ // client\n+ // .add_relay(\"wss://relay.damus.io\")\n+ // .await\n+ // .expect(\"failed to add damus relay\");\n+ // client\n+ // .add_relay(\"wss://nos.lol\")\n+ // .await\n+ // .expect(\"failed to add nos.lol relay\");\n+ // client.connect().await; // connect() likely doesn't return a Result you can match on\n+ // let builder = EventBuilder::text_note(serialized_commit.clone());\n+ // let output = client\n+ // .send_event_builder(builder)\n+ // .await\n+ // .expect(\"589:failed to send event\");\n+ // info!(\"Event ID: {}\", output.id());\n+ // info!(\n+ // \"Event ID BECH32: {}\",\n+ // output\n+ // .id()\n+ // //.public_key()\n+ // .to_bech32()\n+ // .expect(\"failed to convert to bech32\")\n+ // );\n+ // info!(\"Sent to: {:?}\", output.success);\n+ // info!(\"Not sent to: {:?}\", output.failed);\n+ // });\n+ //\n+ // //std::process::exit(0);\n+ //\n+ // //P2P CHAT\n+ // let mut app = ui::App::default();\n+ //\n+ // //TODO\n+ // //for line in TITLE.lines() {\n+ // // app.add_message(\n+ // // Msg::default()\n+ // // .set_content(line.to_string())\n+ // // .set_kind(MsgKind::Raw),\n+ // // );\n+ // //}\n+ //\n+ // use crate::chat::generate_nostr_keys_from_commit_hash;\n+ // let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // info!(\"keys.public_key():\\n{}\", keys.public_key());\n // app.add_message(\n // Msg::default()\n- // .set_content(line.to_string())\n+ // .set_content(keys.public_key().to_string())\n // .set_kind(MsgKind::Raw),\n // );\n- //}\n-\n- use crate::chat::generate_nostr_keys_from_commit_hash;\n- let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- info!(\"keys.public_key():\\n{}\", keys.public_key());\n- app.add_message(\n- Msg::default()\n- .set_content(keys.public_key().to_string())\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"second message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"third message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"fourth message\"))\n- .set_kind(MsgKind::Raw),\n- );\n-\n- let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n- let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n-\n- // let input_loop_fut = input_loop(input_tx);\n- let input_tx_clone = input_tx.clone();\n- app.on_submit(move |m| {\n- debug!(\"sent: {:?}\", m);\n- input_tx_clone.blocking_send(m).unwrap();\n- });\n-\n- let topic = if args.topic.is_some() {\n- args.topic.clone()\n- } else {\n- Some(String::from(commit_id.to_string()))\n- };\n-\n- app.topic = topic.clone().unwrap();\n-\n- let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n-\n- global_rt().spawn(async move {\n- evt_loop(input_rx, peer_tx, topic).await.unwrap();\n- });\n-\n- // recv from peer\n- let mut tui_msg_adder = app.add_msg_fn();\n- global_rt().spawn(async move {\n- while let Some(m) = peer_rx.recv().await {\n- debug!(\"recv: {:?}\", m);\n- tui_msg_adder(m);\n- }\n- });\n-\n- // say hi\n- let input_tx_clone = input_tx.clone();\n- global_rt().spawn(async move {\n- tokio::time::sleep(Duration::from_millis(1000)).await;\n- input_tx_clone\n- .send(Msg::default().set_kind(MsgKind::Join))\n- .await\n- .unwrap();\n- });\n-\n- app.run()?;\n-\n- // say goodbye\n- input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n- std::thread::sleep(Duration::from_millis(500));\n-\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"second message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"third message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"fourth message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ //\n+ // let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n+ // let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n+ //\n+ // // let input_loop_fut = input_loop(input_tx);\n+ // let input_tx_clone = input_tx.clone();\n+ // app.on_submit(move |m| {\n+ // debug!(\"sent: {:?}\", m);\n+ // input_tx_clone.blocking_send(m).unwrap();\n+ // });\n+ //\n+ // let topic = if args.topic.is_some() {\n+ // args.topic.clone()\n+ // } else {\n+ // Some(String::from(commit_id.to_string()))\n+ // };\n+ //\n+ // app.topic = topic.clone().unwrap();\n+ //\n+ // let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n+ //\n+ // global_rt().spawn(async move {\n+ // evt_loop(input_rx, peer_tx, topic).await.unwrap();\n+ // });\n+ //\n+ // // recv from peer\n+ // let mut tui_msg_adder = app.add_msg_fn();\n+ // global_rt().spawn(async move {\n+ // while let Some(m) = peer_rx.recv().await {\n+ // debug!(\"recv: {:?}\", m);\n+ // tui_msg_adder(m);\n+ // }\n+ // });\n+ //\n+ // // say hi\n+ // let input_tx_clone = input_tx.clone();\n+ // global_rt().spawn(async move {\n+ // tokio::time::sleep(Duration::from_millis(1000)).await;\n+ // input_tx_clone\n+ // .send(Msg::default().set_kind(MsgKind::Join))\n+ // .await\n+ // .unwrap();\n+ // });\n+ //\n+ // app.run()?;\n+ //\n+ // // say goodbye\n+ // input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n+ // std::thread::sleep(Duration::from_millis(500));\n+ //\n Ok(())\n }\ndiff --git a/src/lib/sub_commands/fetch.rs b/src/lib/sub_commands/fetch.rs\nindex d6343357..2c05425c 100644\n--- a/src/lib/sub_commands/fetch.rs\n+++ b/src/lib/sub_commands/fetch.rs\n@@ -11,7 +11,7 @@ use crate::{\n repo_ref::get_repo_coordinates,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// address pointer to repo announcement\n #[arg(long, action)]\ndiff --git a/src/lib/sub_commands/login.rs b/src/lib/sub_commands/login.rs\nindex 78ea3a58..176a7043 100644\n--- a/src/lib/sub_commands/login.rs\n+++ b/src/lib/sub_commands/login.rs\n@@ -8,7 +8,7 @@ use crate::{\n login,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// don't fetch user metadata and relay list from relays\n #[arg(long, action)]\n","time":1746136255}

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

{"id":"d685d2683288d3247933e2de0f42f6dc273dd410","tree":"4302487b1f8c4b6048436b70bdcd2a857412aeb5","parents":["34b0e967cfa04f4b42079985ad3f3511e0ac51ef"],"author_name":"randymcmillan","author_email":"randymcmillan@protonmail.com","committer_name":"randymcmillan","committer_email":"randymcmillan@protonmail.com","message":"src/lib/sub_commands/chat.rs:intermediate\n\ndiff --git a/src/lib/cli.rs b/src/lib/cli.rs\nindex c253d97c..a32c01fb 100644\n--- a/src/lib/cli.rs\n+++ b/src/lib/cli.rs\n@@ -44,12 +44,12 @@ pub enum Commands {\n Login(sub_commands::login::SubCommandArgs),\n }\n\n-#[derive(Parser)]\n+#[derive(Parser, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatCli {\n- #[command(subcommand)]\n- pub command: ChatCommands,\n+ // #[command(subcommand)]\n+ // pub command: ChatCommands,\n /// remote signer address\n //#[arg(long, global = true)]\n //pub bunker_uri: Option,\n@@ -67,22 +67,22 @@ pub struct ChatCli {\n //pub disable_cli_spinners: bool,\n }\n\n-#[derive(Subcommand)]\n-pub enum ChatCommands {\n- /// update cache with latest updates from nostr\n- Fetch(sub_commands::fetch::SubCommandArgs),\n- /// signal you are this repo's maintainer accepting proposals via\n- /// nostr\n- Init(sub_commands::init::SubCommandArgs),\n- /// issue commits as a proposal\n- Send(sub_commands::send::SubCommandArgs),\n- /// list proposals; checkout, apply or download selected\n- List,\n- /// send proposal revision\n- Push(sub_commands::push::SubCommandArgs),\n- /// fetch and apply new proposal commits / revisions linked to\n- /// branch\n- Pull,\n- /// run with --nsec flag to change npub\n- Login(sub_commands::login::SubCommandArgs),\n-}\n+//#[derive(Subcommand, Debug)]\n+//pub enum ChatCommands {\n+// /// update cache with latest updates from nostr\n+// Fetch(sub_commands::fetch::SubCommandArgs),\n+// /// signal you are this repo's maintainer accepting proposals via\n+// /// nostr\n+// Init(sub_commands::init::SubCommandArgs),\n+// /// issue commits as a proposal\n+// Send(sub_commands::send::SubCommandArgs),\n+// /// list proposals; checkout, apply or download selected\n+// List,\n+// /// send proposal revision\n+// Push(sub_commands::push::SubCommandArgs),\n+// /// fetch and apply new proposal commits / revisions linked to\n+// /// branch\n+// Pull,\n+// /// run with --nsec flag to change npub\n+// Login(sub_commands::login::SubCommandArgs),\n+//}\ndiff --git a/src/lib/sub_commands/chat.rs b/src/lib/sub_commands/chat.rs\nindex 68edc3d3..bec002f5 100644\n--- a/src/lib/sub_commands/chat.rs\n+++ b/src/lib/sub_commands/chat.rs\n@@ -1,6 +1,6 @@\n #![cfg_attr(not(test), warn(clippy::pedantic))]\n #![cfg_attr(not(test), warn(clippy::expect_used))]\n-use crate::cli::ChatCommands;\n+//use crate::cli::ChatCommands;\n use crate::sub_commands::fetch;\n use crate::sub_commands::init;\n use crate::sub_commands::list;\n@@ -44,12 +44,12 @@ use tracing::{debug, info, Level};\n use tracing_subscriber::util::SubscriberInitExt;\n use tracing_subscriber::{fmt, layer::SubscriberExt, EnvFilter, Registry};\n\n-#[derive(Args)]\n+#[derive(Args, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatSubCommand {\n- #[command(subcommand)]\n- command: ChatCommands,\n+ //#[command(subcommand)]\n+ //command: ChatCommands,\n ///// nsec or hex private key\n #[arg(short, long, global = true)]\n nsec: Option,\n@@ -73,366 +73,367 @@ pub struct ChatSubCommand {\n }\n\n pub async fn chat(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- match &sub_command_args.command {\n- ChatCommands::Login(args) => login::launch(&args).await?,\n- ChatCommands::Init(args) => init::launch(&args).await?,\n- ChatCommands::Send(args) => send::launch(&args, true).await?,\n- ChatCommands::List => list::launch().await?,\n- ChatCommands::Pull => pull::launch().await?,\n- ChatCommands::Push(args) => push::launch(&args).await?,\n- ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n-\t\t_ => return Ok(()),\n-\t}\n- //continue\n-\n- run(sub_command_args);\n+ //match &sub_command_args.command {\n+ //// ChatCommands::Login(args) => login::launch(&args).await?,\n+ //// ChatCommands::Init(args) => init::launch(&args).await?,\n+ //// ChatCommands::Send(args) => send::launch(&args, true).await?,\n+ //// ChatCommands::List => list::launch().await?,\n+ //// ChatCommands::Pull => pull::launch().await?,\n+ //// ChatCommands::Push(args) => push::launch(&args).await?,\n+ //// ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n+ //\t_ => { run(sub_command_args).await? }\n+ //}\n+ run(sub_command_args).await?;\n\n Ok(())\n }\n\n pub async fn run(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- let args = sub_command_args;\n-\n- if let Some(name) = args.name.clone() {\n- use std::env;\n- env::set_var(\"USER\", &name);\n- };\n-\n- let level = if args.debug {\n- Level::DEBUG\n- } else if args.trace {\n- Level::TRACE\n- } else if args.info {\n- Level::INFO\n- } else {\n- Level::WARN\n- };\n-\n- let filter = EnvFilter::default()\n- .add_directive(level.into())\n- .add_directive(\"nostr_sdk=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n- .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n- .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n- .add_directive(\"gnostr::message=off\".parse().unwrap())\n- .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n- .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n- //\n- .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n-\n- let subscriber = Registry::default()\n- .with(fmt::layer().with_writer(std::io::stdout))\n- .with(filter);\n-\n- let _ = subscriber.try_init();\n-\n- if args.debug || args.trace {\n- if args.nsec.clone().is_some() {\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n- print!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- print!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n- }\n- }\n- //parse keys from sha256 hash\n- let empty_hash_keys =\n- Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n-\n- if args.nsec.is_some() {\n- //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n-\n- info!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n-\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\")?;\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head()?;\n- let obj = head.resolve()?.peel(ObjectType::Commit)?;\n-\n- //read top commit\n- let commit = obj.peel_to_commit()?;\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"416:commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id);\n- info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n-\n- //// commit based keys\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n- custom_tags.insert(\n- padded_keys.clone().public_key().to_string(),\n- vec![\"GNOSTR\".to_string()],\n- );\n-\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n- info!(\"467:signed_event:\\n{:?}\", signed_event);\n- });\n-\n- //TODO config metadata\n-\n- //access some git info\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- let binding = serialized_commit.clone();\n- let deserialized_commit = deserialize_commit(&repo, &binding)?;\n- info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n-\n- //access commit summary in the deserialized commit\n- info!(\"481:Original commit ID:\\n{}\", commit_id);\n- info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n-\n- //additional checking\n- if commit.id() != deserialized_commit.id() {\n- debug!(\"Commit IDs do not match!\");\n- } else {\n- debug!(\"Commit IDs match!\");\n- }\n-\n- let value: Value = parse_json(&serialized_commit)?;\n- //info!(\"value:\\n{}\", value);\n-\n- // Accessing object elements.\n- if let Some(id) = value.get(\"id\") {\n- info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n- }\n- if let Some(tree) = value.get(\"tree\") {\n- info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n- }\n- // Accessing parent commits (merge may be array)\n- if let Some(parent) = value.get(\"parents\") {\n- if let Value::Array(arr) = parent {\n- if let Some(parent) = arr.get(0) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n- }\n- if let Some(parent) = arr.get(1) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n- }\n- }\n- }\n- if let Some(author_name) = value.get(\"author_name\") {\n- info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(author_email) = value.get(\"author_email\") {\n- info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_name) = value.get(\"committer_name\") {\n- info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_email) = value.get(\"committer_email\") {\n- info!(\n- \"committer_email:\\n{}\",\n- committer_email.as_str().unwrap_or(\"\")\n- );\n- }\n-\n- //split the commit message into a Vec\n- if let Some(message) = value.get(\"message\") {\n- let parts = split_json_string(&message, \"\\n\");\n- for part in parts {\n- info!(\"\\n{}\", part);\n- }\n- debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n- }\n- if let Value::Number(time) = &value[\"time\"] {\n- info!(\"time:\\n{}\", time);\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\").expect(\"\");\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head().expect(\"\");\n- let obj = head\n- .resolve()\n- .expect(\"\")\n- .peel(ObjectType::Commit)\n- .expect(\"\");\n-\n- //read top commit\n- let commit = obj.peel_to_commit().expect(\"\");\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n- //// commit based keys\n- //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n- //create nostr client with commit based keys\n- //let client = Client::new(keys);\n- let client = Client::new(padded_keys.clone());\n- global_rt().spawn(async move {\n- client\n- .add_relay(\"wss://relay.damus.io\")\n- .await\n- .expect(\"failed to add damus relay\");\n- client\n- .add_relay(\"wss://nos.lol\")\n- .await\n- .expect(\"failed to add nos.lol relay\");\n- client.connect().await; // connect() likely doesn't return a Result you can match on\n- let builder = EventBuilder::text_note(serialized_commit.clone());\n- let output = client\n- .send_event_builder(builder)\n- .await\n- .expect(\"589:failed to send event\");\n- info!(\"Event ID: {}\", output.id());\n- info!(\n- \"Event ID BECH32: {}\",\n- output\n- .id()\n- //.public_key()\n- .to_bech32()\n- .expect(\"failed to convert to bech32\")\n- );\n- info!(\"Sent to: {:?}\", output.success);\n- info!(\"Not sent to: {:?}\", output.failed);\n- });\n-\n- //std::process::exit(0);\n-\n- //P2P CHAT\n- let mut app = ui::App::default();\n-\n- //TODO\n- //for line in TITLE.lines() {\n+ println!(\"{:?}\", &sub_command_args);\n+ let chat = chat;\n+\n+ // let args = sub_command_args;\n+ //\n+ // if let Some(name) = args.name.clone() {\n+ // use std::env;\n+ // env::set_var(\"USER\", &name);\n+ // };\n+ //\n+ // let level = if args.debug {\n+ // Level::DEBUG\n+ // } else if args.trace {\n+ // Level::TRACE\n+ // } else if args.info {\n+ // Level::INFO\n+ // } else {\n+ // Level::WARN\n+ // };\n+ //\n+ // let filter = EnvFilter::default()\n+ // .add_directive(level.into())\n+ // .add_directive(\"nostr_sdk=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n+ // .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::message=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n+ // .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n+ // //\n+ // .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n+ //\n+ // let subscriber = Registry::default()\n+ // .with(fmt::layer().with_writer(std::io::stdout))\n+ // .with(filter);\n+ //\n+ // let _ = subscriber.try_init();\n+ //\n+ // if args.debug || args.trace {\n+ // if args.nsec.clone().is_some() {\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ // debug!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // debug!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ // }\n+ // }\n+ // //parse keys from sha256 hash\n+ // let empty_hash_keys =\n+ // Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // if args.nsec.is_some() {\n+ // //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ //\n+ // info!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ //\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\")?;\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head()?;\n+ // let obj = head.resolve()?.peel(ObjectType::Commit)?;\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit()?;\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"416:commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id);\n+ // info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n+ //\n+ // //// commit based keys\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ // custom_tags.insert(\n+ // padded_keys.clone().public_key().to_string(),\n+ // vec![\"GNOSTR\".to_string()],\n+ // );\n+ //\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n+ // info!(\"467:signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // //TODO config metadata\n+ //\n+ // //access some git info\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // let binding = serialized_commit.clone();\n+ // let deserialized_commit = deserialize_commit(&repo, &binding)?;\n+ // info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n+ //\n+ // //access commit summary in the deserialized commit\n+ // info!(\"481:Original commit ID:\\n{}\", commit_id);\n+ // info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n+ //\n+ // //additional checking\n+ // if commit.id() != deserialized_commit.id() {\n+ // debug!(\"Commit IDs do not match!\");\n+ // } else {\n+ // debug!(\"Commit IDs match!\");\n+ // }\n+ //\n+ // let value: Value = parse_json(&serialized_commit)?;\n+ // //info!(\"value:\\n{}\", value);\n+ //\n+ // // Accessing object elements.\n+ // if let Some(id) = value.get(\"id\") {\n+ // info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(tree) = value.get(\"tree\") {\n+ // info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n+ // }\n+ // // Accessing parent commits (merge may be array)\n+ // if let Some(parent) = value.get(\"parents\") {\n+ // if let Value::Array(arr) = parent {\n+ // if let Some(parent) = arr.get(0) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n+ // }\n+ // if let Some(parent) = arr.get(1) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n+ // }\n+ // }\n+ // }\n+ // if let Some(author_name) = value.get(\"author_name\") {\n+ // info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(author_email) = value.get(\"author_email\") {\n+ // info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_name) = value.get(\"committer_name\") {\n+ // info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_email) = value.get(\"committer_email\") {\n+ // info!(\n+ // \"committer_email:\\n{}\",\n+ // committer_email.as_str().unwrap_or(\"\")\n+ // );\n+ // }\n+ //\n+ // //split the commit message into a Vec\n+ // if let Some(message) = value.get(\"message\") {\n+ // let parts = split_json_string(&message, \"\\n\");\n+ // for part in parts {\n+ // info!(\"\\n{}\", part);\n+ // }\n+ // debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Value::Number(time) = &value[\"time\"] {\n+ // info!(\"time:\\n{}\", time);\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\").expect(\"\");\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head().expect(\"\");\n+ // let obj = head\n+ // .resolve()\n+ // .expect(\"\")\n+ // .peel(ObjectType::Commit)\n+ // .expect(\"\");\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit().expect(\"\");\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n+ // //// commit based keys\n+ // //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ // //create nostr client with commit based keys\n+ // //let client = Client::new(keys);\n+ // let client = Client::new(padded_keys.clone());\n+ // global_rt().spawn(async move {\n+ // client\n+ // .add_relay(\"wss://relay.damus.io\")\n+ // .await\n+ // .expect(\"failed to add damus relay\");\n+ // client\n+ // .add_relay(\"wss://nos.lol\")\n+ // .await\n+ // .expect(\"failed to add nos.lol relay\");\n+ // client.connect().await; // connect() likely doesn't return a Result you can match on\n+ // let builder = EventBuilder::text_note(serialized_commit.clone());\n+ // let output = client\n+ // .send_event_builder(builder)\n+ // .await\n+ // .expect(\"589:failed to send event\");\n+ // info!(\"Event ID: {}\", output.id());\n+ // info!(\n+ // \"Event ID BECH32: {}\",\n+ // output\n+ // .id()\n+ // //.public_key()\n+ // .to_bech32()\n+ // .expect(\"failed to convert to bech32\")\n+ // );\n+ // info!(\"Sent to: {:?}\", output.success);\n+ // info!(\"Not sent to: {:?}\", output.failed);\n+ // });\n+ //\n+ // //std::process::exit(0);\n+ //\n+ // //P2P CHAT\n+ // let mut app = ui::App::default();\n+ //\n+ // //TODO\n+ // //for line in TITLE.lines() {\n+ // // app.add_message(\n+ // // Msg::default()\n+ // // .set_content(line.to_string())\n+ // // .set_kind(MsgKind::Raw),\n+ // // );\n+ // //}\n+ //\n+ // use crate::chat::generate_nostr_keys_from_commit_hash;\n+ // let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // info!(\"keys.public_key():\\n{}\", keys.public_key());\n // app.add_message(\n // Msg::default()\n- // .set_content(line.to_string())\n+ // .set_content(keys.public_key().to_string())\n // .set_kind(MsgKind::Raw),\n // );\n- //}\n-\n- use crate::chat::generate_nostr_keys_from_commit_hash;\n- let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- info!(\"keys.public_key():\\n{}\", keys.public_key());\n- app.add_message(\n- Msg::default()\n- .set_content(keys.public_key().to_string())\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"second message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"third message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"fourth message\"))\n- .set_kind(MsgKind::Raw),\n- );\n-\n- let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n- let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n-\n- // let input_loop_fut = input_loop(input_tx);\n- let input_tx_clone = input_tx.clone();\n- app.on_submit(move |m| {\n- debug!(\"sent: {:?}\", m);\n- input_tx_clone.blocking_send(m).unwrap();\n- });\n-\n- let topic = if args.topic.is_some() {\n- args.topic.clone()\n- } else {\n- Some(String::from(commit_id.to_string()))\n- };\n-\n- app.topic = topic.clone().unwrap();\n-\n- let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n-\n- global_rt().spawn(async move {\n- evt_loop(input_rx, peer_tx, topic).await.unwrap();\n- });\n-\n- // recv from peer\n- let mut tui_msg_adder = app.add_msg_fn();\n- global_rt().spawn(async move {\n- while let Some(m) = peer_rx.recv().await {\n- debug!(\"recv: {:?}\", m);\n- tui_msg_adder(m);\n- }\n- });\n-\n- // say hi\n- let input_tx_clone = input_tx.clone();\n- global_rt().spawn(async move {\n- tokio::time::sleep(Duration::from_millis(1000)).await;\n- input_tx_clone\n- .send(Msg::default().set_kind(MsgKind::Join))\n- .await\n- .unwrap();\n- });\n-\n- app.run()?;\n-\n- // say goodbye\n- input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n- std::thread::sleep(Duration::from_millis(500));\n-\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"second message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"third message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"fourth message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ //\n+ // let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n+ // let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n+ //\n+ // // let input_loop_fut = input_loop(input_tx);\n+ // let input_tx_clone = input_tx.clone();\n+ // app.on_submit(move |m| {\n+ // debug!(\"sent: {:?}\", m);\n+ // input_tx_clone.blocking_send(m).unwrap();\n+ // });\n+ //\n+ // let topic = if args.topic.is_some() {\n+ // args.topic.clone()\n+ // } else {\n+ // Some(String::from(commit_id.to_string()))\n+ // };\n+ //\n+ // app.topic = topic.clone().unwrap();\n+ //\n+ // let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n+ //\n+ // global_rt().spawn(async move {\n+ // evt_loop(input_rx, peer_tx, topic).await.unwrap();\n+ // });\n+ //\n+ // // recv from peer\n+ // let mut tui_msg_adder = app.add_msg_fn();\n+ // global_rt().spawn(async move {\n+ // while let Some(m) = peer_rx.recv().await {\n+ // debug!(\"recv: {:?}\", m);\n+ // tui_msg_adder(m);\n+ // }\n+ // });\n+ //\n+ // // say hi\n+ // let input_tx_clone = input_tx.clone();\n+ // global_rt().spawn(async move {\n+ // tokio::time::sleep(Duration::from_millis(1000)).await;\n+ // input_tx_clone\n+ // .send(Msg::default().set_kind(MsgKind::Join))\n+ // .await\n+ // .unwrap();\n+ // });\n+ //\n+ // app.run()?;\n+ //\n+ // // say goodbye\n+ // input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n+ // std::thread::sleep(Duration::from_millis(500));\n+ //\n Ok(())\n }\ndiff --git a/src/lib/sub_commands/fetch.rs b/src/lib/sub_commands/fetch.rs\nindex d6343357..2c05425c 100644\n--- a/src/lib/sub_commands/fetch.rs\n+++ b/src/lib/sub_commands/fetch.rs\n@@ -11,7 +11,7 @@ use crate::{\n repo_ref::get_repo_coordinates,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// address pointer to repo announcement\n #[arg(long, action)]\ndiff --git a/src/lib/sub_commands/login.rs b/src/lib/sub_commands/login.rs\nindex 78ea3a58..176a7043 100644\n--- a/src/lib/sub_commands/login.rs\n+++ b/src/lib/sub_commands/login.rs\n@@ -8,7 +8,7 @@ use crate::{\n login,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// don't fetch user metadata and relay list from relays\n #[arg(long, action)]\n","time":1746136255}

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

{"id":"d685d2683288d3247933e2de0f42f6dc273dd410","tree":"4302487b1f8c4b6048436b70bdcd2a857412aeb5","parents":["34b0e967cfa04f4b42079985ad3f3511e0ac51ef"],"author_name":"randymcmillan","author_email":"randymcmillan@protonmail.com","committer_name":"randymcmillan","committer_email":"randymcmillan@protonmail.com","message":"src/lib/sub_commands/chat.rs:intermediate\n\ndiff --git a/src/lib/cli.rs b/src/lib/cli.rs\nindex c253d97c..a32c01fb 100644\n--- a/src/lib/cli.rs\n+++ b/src/lib/cli.rs\n@@ -44,12 +44,12 @@ pub enum Commands {\n Login(sub_commands::login::SubCommandArgs),\n }\n\n-#[derive(Parser)]\n+#[derive(Parser, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatCli {\n- #[command(subcommand)]\n- pub command: ChatCommands,\n+ // #[command(subcommand)]\n+ // pub command: ChatCommands,\n /// remote signer address\n //#[arg(long, global = true)]\n //pub bunker_uri: Option,\n@@ -67,22 +67,22 @@ pub struct ChatCli {\n //pub disable_cli_spinners: bool,\n }\n\n-#[derive(Subcommand)]\n-pub enum ChatCommands {\n- /// update cache with latest updates from nostr\n- Fetch(sub_commands::fetch::SubCommandArgs),\n- /// signal you are this repo's maintainer accepting proposals via\n- /// nostr\n- Init(sub_commands::init::SubCommandArgs),\n- /// issue commits as a proposal\n- Send(sub_commands::send::SubCommandArgs),\n- /// list proposals; checkout, apply or download selected\n- List,\n- /// send proposal revision\n- Push(sub_commands::push::SubCommandArgs),\n- /// fetch and apply new proposal commits / revisions linked to\n- /// branch\n- Pull,\n- /// run with --nsec flag to change npub\n- Login(sub_commands::login::SubCommandArgs),\n-}\n+//#[derive(Subcommand, Debug)]\n+//pub enum ChatCommands {\n+// /// update cache with latest updates from nostr\n+// Fetch(sub_commands::fetch::SubCommandArgs),\n+// /// signal you are this repo's maintainer accepting proposals via\n+// /// nostr\n+// Init(sub_commands::init::SubCommandArgs),\n+// /// issue commits as a proposal\n+// Send(sub_commands::send::SubCommandArgs),\n+// /// list proposals; checkout, apply or download selected\n+// List,\n+// /// send proposal revision\n+// Push(sub_commands::push::SubCommandArgs),\n+// /// fetch and apply new proposal commits / revisions linked to\n+// /// branch\n+// Pull,\n+// /// run with --nsec flag to change npub\n+// Login(sub_commands::login::SubCommandArgs),\n+//}\ndiff --git a/src/lib/sub_commands/chat.rs b/src/lib/sub_commands/chat.rs\nindex 68edc3d3..bec002f5 100644\n--- a/src/lib/sub_commands/chat.rs\n+++ b/src/lib/sub_commands/chat.rs\n@@ -1,6 +1,6 @@\n #![cfg_attr(not(test), warn(clippy::pedantic))]\n #![cfg_attr(not(test), warn(clippy::expect_used))]\n-use crate::cli::ChatCommands;\n+//use crate::cli::ChatCommands;\n use crate::sub_commands::fetch;\n use crate::sub_commands::init;\n use crate::sub_commands::list;\n@@ -44,12 +44,12 @@ use tracing::{debug, info, Level};\n use tracing_subscriber::util::SubscriberInitExt;\n use tracing_subscriber::{fmt, layer::SubscriberExt, EnvFilter, Registry};\n\n-#[derive(Args)]\n+#[derive(Args, Debug)]\n #[command(author, version, about, long_about = None)]\n #[command(propagate_version = true)]\n pub struct ChatSubCommand {\n- #[command(subcommand)]\n- command: ChatCommands,\n+ //#[command(subcommand)]\n+ //command: ChatCommands,\n ///// nsec or hex private key\n #[arg(short, long, global = true)]\n nsec: Option,\n@@ -73,366 +73,367 @@ pub struct ChatSubCommand {\n }\n\n pub async fn chat(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- match &sub_command_args.command {\n- ChatCommands::Login(args) => login::launch(&args).await?,\n- ChatCommands::Init(args) => init::launch(&args).await?,\n- ChatCommands::Send(args) => send::launch(&args, true).await?,\n- ChatCommands::List => list::launch().await?,\n- ChatCommands::Pull => pull::launch().await?,\n- ChatCommands::Push(args) => push::launch(&args).await?,\n- ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n-\t\t_ => return Ok(()),\n-\t}\n- //continue\n-\n- run(sub_command_args);\n+ //match &sub_command_args.command {\n+ //// ChatCommands::Login(args) => login::launch(&args).await?,\n+ //// ChatCommands::Init(args) => init::launch(&args).await?,\n+ //// ChatCommands::Send(args) => send::launch(&args, true).await?,\n+ //// ChatCommands::List => list::launch().await?,\n+ //// ChatCommands::Pull => pull::launch().await?,\n+ //// ChatCommands::Push(args) => push::launch(&args).await?,\n+ //// ChatCommands::Fetch(args) => fetch::launch(&args).await?,\n+ //\t_ => { run(sub_command_args).await? }\n+ //}\n+ run(sub_command_args).await?;\n\n Ok(())\n }\n\n pub async fn run(sub_command_args: &ChatSubCommand) -> Result<(), Box> {\n- let args = sub_command_args;\n-\n- if let Some(name) = args.name.clone() {\n- use std::env;\n- env::set_var(\"USER\", &name);\n- };\n-\n- let level = if args.debug {\n- Level::DEBUG\n- } else if args.trace {\n- Level::TRACE\n- } else if args.info {\n- Level::INFO\n- } else {\n- Level::WARN\n- };\n-\n- let filter = EnvFilter::default()\n- .add_directive(level.into())\n- .add_directive(\"nostr_sdk=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n- .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n- .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n- .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n- .add_directive(\"gnostr::message=off\".parse().unwrap())\n- .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n- .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n- //\n- .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n-\n- let subscriber = Registry::default()\n- .with(fmt::layer().with_writer(std::io::stdout))\n- .with(filter);\n-\n- let _ = subscriber.try_init();\n-\n- if args.debug || args.trace {\n- if args.nsec.clone().is_some() {\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n- print!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- print!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n- }\n- }\n- //parse keys from sha256 hash\n- let empty_hash_keys =\n- Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n-\n- if args.nsec.is_some() {\n- //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n- let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n-\n- info!(\n- \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n- keys.secret_key().display_secret()\n- );\n- info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n-\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n- info!(\"signed_event:\\n{:?}\", signed_event);\n- });\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\")?;\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head()?;\n- let obj = head.resolve()?.peel(ObjectType::Commit)?;\n-\n- //read top commit\n- let commit = obj.peel_to_commit()?;\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"416:commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id);\n- info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n-\n- //// commit based keys\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n-\n- //create a HashMap of custom_tags\n- //used to insert commit tags\n- let mut custom_tags = HashMap::new();\n- custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n- custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n- custom_tags.insert(\n- padded_keys.clone().public_key().to_string(),\n- vec![\"GNOSTR\".to_string()],\n- );\n-\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- global_rt().spawn(async move {\n- //send to create_event function with &\"custom content\"\n- let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n- info!(\"467:signed_event:\\n{:?}\", signed_event);\n- });\n-\n- //TODO config metadata\n-\n- //access some git info\n- let serialized_commit = serialize_commit(&commit)?;\n- info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n-\n- let binding = serialized_commit.clone();\n- let deserialized_commit = deserialize_commit(&repo, &binding)?;\n- info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n-\n- //access commit summary in the deserialized commit\n- info!(\"481:Original commit ID:\\n{}\", commit_id);\n- info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n-\n- //additional checking\n- if commit.id() != deserialized_commit.id() {\n- debug!(\"Commit IDs do not match!\");\n- } else {\n- debug!(\"Commit IDs match!\");\n- }\n-\n- let value: Value = parse_json(&serialized_commit)?;\n- //info!(\"value:\\n{}\", value);\n-\n- // Accessing object elements.\n- if let Some(id) = value.get(\"id\") {\n- info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n- }\n- if let Some(tree) = value.get(\"tree\") {\n- info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n- }\n- // Accessing parent commits (merge may be array)\n- if let Some(parent) = value.get(\"parents\") {\n- if let Value::Array(arr) = parent {\n- if let Some(parent) = arr.get(0) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n- }\n- if let Some(parent) = arr.get(1) {\n- info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n- }\n- }\n- }\n- if let Some(author_name) = value.get(\"author_name\") {\n- info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(author_email) = value.get(\"author_email\") {\n- info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_name) = value.get(\"committer_name\") {\n- info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n- }\n- if let Some(committer_email) = value.get(\"committer_email\") {\n- info!(\n- \"committer_email:\\n{}\",\n- committer_email.as_str().unwrap_or(\"\")\n- );\n- }\n-\n- //split the commit message into a Vec\n- if let Some(message) = value.get(\"message\") {\n- let parts = split_json_string(&message, \"\\n\");\n- for part in parts {\n- info!(\"\\n{}\", part);\n- }\n- debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n- }\n- if let Value::Number(time) = &value[\"time\"] {\n- info!(\"time:\\n{}\", time);\n- }\n-\n- //initialize git repo\n- let repo = Repository::discover(\".\").expect(\"\");\n-\n- //gather some repo info\n- //find HEAD\n- let head = repo.head().expect(\"\");\n- let obj = head\n- .resolve()\n- .expect(\"\")\n- .peel(ObjectType::Commit)\n- .expect(\"\");\n-\n- //read top commit\n- let commit = obj.peel_to_commit().expect(\"\");\n- let commit_id = commit.id().to_string();\n- //some info wrangling\n- info!(\"commit_id:\\n{}\", commit_id);\n- let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n- //// commit based keys\n- //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n- //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- //info!(\"keys.public_key():\\n{}\", keys.public_key());\n-\n- //parse keys from sha256 hash\n- let padded_keys = Keys::parse(padded_commit_id).unwrap();\n- //create nostr client with commit based keys\n- //let client = Client::new(keys);\n- let client = Client::new(padded_keys.clone());\n- global_rt().spawn(async move {\n- client\n- .add_relay(\"wss://relay.damus.io\")\n- .await\n- .expect(\"failed to add damus relay\");\n- client\n- .add_relay(\"wss://nos.lol\")\n- .await\n- .expect(\"failed to add nos.lol relay\");\n- client.connect().await; // connect() likely doesn't return a Result you can match on\n- let builder = EventBuilder::text_note(serialized_commit.clone());\n- let output = client\n- .send_event_builder(builder)\n- .await\n- .expect(\"589:failed to send event\");\n- info!(\"Event ID: {}\", output.id());\n- info!(\n- \"Event ID BECH32: {}\",\n- output\n- .id()\n- //.public_key()\n- .to_bech32()\n- .expect(\"failed to convert to bech32\")\n- );\n- info!(\"Sent to: {:?}\", output.success);\n- info!(\"Not sent to: {:?}\", output.failed);\n- });\n-\n- //std::process::exit(0);\n-\n- //P2P CHAT\n- let mut app = ui::App::default();\n-\n- //TODO\n- //for line in TITLE.lines() {\n+ println!(\"{:?}\", &sub_command_args);\n+ let chat = chat;\n+\n+ // let args = sub_command_args;\n+ //\n+ // if let Some(name) = args.name.clone() {\n+ // use std::env;\n+ // env::set_var(\"USER\", &name);\n+ // };\n+ //\n+ // let level = if args.debug {\n+ // Level::DEBUG\n+ // } else if args.trace {\n+ // Level::TRACE\n+ // } else if args.info {\n+ // Level::INFO\n+ // } else {\n+ // Level::WARN\n+ // };\n+ //\n+ // let filter = EnvFilter::default()\n+ // .add_directive(level.into())\n+ // .add_directive(\"nostr_sdk=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::client::handler=off\".parse().unwrap())\n+ // .add_directive(\"nostr_relay_pool=off\".parse().unwrap())\n+ // .add_directive(\"nostr_sdk::relay::connection=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::chat::p2p=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::message=off\".parse().unwrap())\n+ // .add_directive(\"gnostr::nostr_proto=off\".parse().unwrap())\n+ // .add_directive(\"libp2p_mdns::behaviour::iface=off\".parse().unwrap())\n+ // //\n+ // .add_directive(\"libp2p_gossipsub::behaviour=off\".parse().unwrap());\n+ //\n+ // let subscriber = Registry::default()\n+ // .with(fmt::layer().with_writer(std::io::stdout))\n+ // .with(filter);\n+ //\n+ // let _ = subscriber.try_init();\n+ //\n+ // if args.debug || args.trace {\n+ // if args.nsec.clone().is_some() {\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ // debug!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // debug!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ // }\n+ // }\n+ // //parse keys from sha256 hash\n+ // let empty_hash_keys =\n+ // Keys::parse(\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\").unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(empty_hash_keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // if args.nsec.is_some() {\n+ // //let keys = Keys::parse(&args.nsec.unwrap().clone()).unwrap();\n+ // let keys = Keys::parse(&args.nsec.clone().unwrap().clone()).unwrap();\n+ //\n+ // info!(\n+ // \"{{\\\"private_key\\\":\\\"{}\\\"}}\",\n+ // keys.secret_key().display_secret()\n+ // );\n+ // info!(\"{{\\\"public_key\\\":\\\"{}\\\"}}\", keys.public_key());\n+ //\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(keys, custom_tags, &\"gnostr-chat:event\").await;\n+ // info!(\"signed_event:\\n{:?}\", signed_event);\n+ // });\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\")?;\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head()?;\n+ // let obj = head.resolve()?.peel(ObjectType::Commit)?;\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit()?;\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"416:commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id);\n+ // info!(\"418:padded_commit_id:\\n{}\", padded_commit_id);\n+ //\n+ // //// commit based keys\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ //\n+ // //create a HashMap of custom_tags\n+ // //used to insert commit tags\n+ // let mut custom_tags = HashMap::new();\n+ // custom_tags.insert(\"gnostr\".to_string(), vec![\"git\".to_string()]);\n+ // custom_tags.insert(\"GIT\".to_string(), vec![\"GNOSTR\".to_string()]);\n+ // custom_tags.insert(\n+ // padded_keys.clone().public_key().to_string(),\n+ // vec![\"GNOSTR\".to_string()],\n+ // );\n+ //\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // global_rt().spawn(async move {\n+ // //send to create_event function with &\"custom content\"\n+ // let signed_event = create_event(padded_keys.clone(), custom_tags, &serialized_commit).await;\n+ // info!(\"467:signed_event:\\n{:?}\", signed_event);\n+ // });\n+ //\n+ // //TODO config metadata\n+ //\n+ // //access some git info\n+ // let serialized_commit = serialize_commit(&commit)?;\n+ // info!(\"476:Serialized commit:\\n{}\", serialized_commit);\n+ //\n+ // let binding = serialized_commit.clone();\n+ // let deserialized_commit = deserialize_commit(&repo, &binding)?;\n+ // info!(\"480:Deserialized commit:\\n{:?}\", deserialized_commit);\n+ //\n+ // //access commit summary in the deserialized commit\n+ // info!(\"481:Original commit ID:\\n{}\", commit_id);\n+ // info!(\"482:Deserialized commit ID:\\n{}\", deserialized_commit.id());\n+ //\n+ // //additional checking\n+ // if commit.id() != deserialized_commit.id() {\n+ // debug!(\"Commit IDs do not match!\");\n+ // } else {\n+ // debug!(\"Commit IDs match!\");\n+ // }\n+ //\n+ // let value: Value = parse_json(&serialized_commit)?;\n+ // //info!(\"value:\\n{}\", value);\n+ //\n+ // // Accessing object elements.\n+ // if let Some(id) = value.get(\"id\") {\n+ // info!(\"id:\\n{}\", id.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(tree) = value.get(\"tree\") {\n+ // info!(\"tree:\\n{}\", tree.as_str().unwrap_or(\"\"));\n+ // }\n+ // // Accessing parent commits (merge may be array)\n+ // if let Some(parent) = value.get(\"parents\") {\n+ // if let Value::Array(arr) = parent {\n+ // if let Some(parent) = arr.get(0) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"initial commit\"));\n+ // }\n+ // if let Some(parent) = arr.get(1) {\n+ // info!(\"parent:\\n{}\", parent.as_str().unwrap_or(\"\"));\n+ // }\n+ // }\n+ // }\n+ // if let Some(author_name) = value.get(\"author_name\") {\n+ // info!(\"author_name:\\n{}\", author_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(author_email) = value.get(\"author_email\") {\n+ // info!(\"author_email:\\n{}\", author_email.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_name) = value.get(\"committer_name\") {\n+ // info!(\"committer_name:\\n{}\", committer_name.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Some(committer_email) = value.get(\"committer_email\") {\n+ // info!(\n+ // \"committer_email:\\n{}\",\n+ // committer_email.as_str().unwrap_or(\"\")\n+ // );\n+ // }\n+ //\n+ // //split the commit message into a Vec\n+ // if let Some(message) = value.get(\"message\") {\n+ // let parts = split_json_string(&message, \"\\n\");\n+ // for part in parts {\n+ // info!(\"\\n{}\", part);\n+ // }\n+ // debug!(\"message:\\n{}\", message.as_str().unwrap_or(\"\"));\n+ // }\n+ // if let Value::Number(time) = &value[\"time\"] {\n+ // info!(\"time:\\n{}\", time);\n+ // }\n+ //\n+ // //initialize git repo\n+ // let repo = Repository::discover(\".\").expect(\"\");\n+ //\n+ // //gather some repo info\n+ // //find HEAD\n+ // let head = repo.head().expect(\"\");\n+ // let obj = head\n+ // .resolve()\n+ // .expect(\"\")\n+ // .peel(ObjectType::Commit)\n+ // .expect(\"\");\n+ //\n+ // //read top commit\n+ // let commit = obj.peel_to_commit().expect(\"\");\n+ // let commit_id = commit.id().to_string();\n+ // //some info wrangling\n+ // info!(\"commit_id:\\n{}\", commit_id);\n+ // let padded_commit_id = format!(\"{:0>64}\", commit_id.clone());\n+ // //// commit based keys\n+ // //use gnostr::chat::generate_nostr_keys_from_commit_hash;\n+ // //let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // //info!(\"keys.public_key():\\n{}\", keys.public_key());\n+ //\n+ // //parse keys from sha256 hash\n+ // let padded_keys = Keys::parse(padded_commit_id).unwrap();\n+ // //create nostr client with commit based keys\n+ // //let client = Client::new(keys);\n+ // let client = Client::new(padded_keys.clone());\n+ // global_rt().spawn(async move {\n+ // client\n+ // .add_relay(\"wss://relay.damus.io\")\n+ // .await\n+ // .expect(\"failed to add damus relay\");\n+ // client\n+ // .add_relay(\"wss://nos.lol\")\n+ // .await\n+ // .expect(\"failed to add nos.lol relay\");\n+ // client.connect().await; // connect() likely doesn't return a Result you can match on\n+ // let builder = EventBuilder::text_note(serialized_commit.clone());\n+ // let output = client\n+ // .send_event_builder(builder)\n+ // .await\n+ // .expect(\"589:failed to send event\");\n+ // info!(\"Event ID: {}\", output.id());\n+ // info!(\n+ // \"Event ID BECH32: {}\",\n+ // output\n+ // .id()\n+ // //.public_key()\n+ // .to_bech32()\n+ // .expect(\"failed to convert to bech32\")\n+ // );\n+ // info!(\"Sent to: {:?}\", output.success);\n+ // info!(\"Not sent to: {:?}\", output.failed);\n+ // });\n+ //\n+ // //std::process::exit(0);\n+ //\n+ // //P2P CHAT\n+ // let mut app = ui::App::default();\n+ //\n+ // //TODO\n+ // //for line in TITLE.lines() {\n+ // // app.add_message(\n+ // // Msg::default()\n+ // // .set_content(line.to_string())\n+ // // .set_kind(MsgKind::Raw),\n+ // // );\n+ // //}\n+ //\n+ // use crate::chat::generate_nostr_keys_from_commit_hash;\n+ // let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n+ // //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n+ // info!(\"keys.public_key():\\n{}\", keys.public_key());\n // app.add_message(\n // Msg::default()\n- // .set_content(line.to_string())\n+ // .set_content(keys.public_key().to_string())\n // .set_kind(MsgKind::Raw),\n // );\n- //}\n-\n- use crate::chat::generate_nostr_keys_from_commit_hash;\n- let keys = generate_nostr_keys_from_commit_hash(&commit_id)?;\n- //info!(\"keys.secret_key():\\n{:?}\", keys.secret_key());\n- info!(\"keys.public_key():\\n{}\", keys.public_key());\n- app.add_message(\n- Msg::default()\n- .set_content(keys.public_key().to_string())\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"second message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"third message\"))\n- .set_kind(MsgKind::Raw),\n- );\n- app.add_message(\n- Msg::default()\n- .set_content(String::from(\"fourth message\"))\n- .set_kind(MsgKind::Raw),\n- );\n-\n- let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n- let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n-\n- // let input_loop_fut = input_loop(input_tx);\n- let input_tx_clone = input_tx.clone();\n- app.on_submit(move |m| {\n- debug!(\"sent: {:?}\", m);\n- input_tx_clone.blocking_send(m).unwrap();\n- });\n-\n- let topic = if args.topic.is_some() {\n- args.topic.clone()\n- } else {\n- Some(String::from(commit_id.to_string()))\n- };\n-\n- app.topic = topic.clone().unwrap();\n-\n- let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n-\n- global_rt().spawn(async move {\n- evt_loop(input_rx, peer_tx, topic).await.unwrap();\n- });\n-\n- // recv from peer\n- let mut tui_msg_adder = app.add_msg_fn();\n- global_rt().spawn(async move {\n- while let Some(m) = peer_rx.recv().await {\n- debug!(\"recv: {:?}\", m);\n- tui_msg_adder(m);\n- }\n- });\n-\n- // say hi\n- let input_tx_clone = input_tx.clone();\n- global_rt().spawn(async move {\n- tokio::time::sleep(Duration::from_millis(1000)).await;\n- input_tx_clone\n- .send(Msg::default().set_kind(MsgKind::Join))\n- .await\n- .unwrap();\n- });\n-\n- app.run()?;\n-\n- // say goodbye\n- input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n- std::thread::sleep(Duration::from_millis(500));\n-\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"second message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"third message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ // app.add_message(\n+ // Msg::default()\n+ // .set_content(String::from(\"fourth message\"))\n+ // .set_kind(MsgKind::Raw),\n+ // );\n+ //\n+ // let (peer_tx, mut peer_rx) = tokio::sync::mpsc::channel::(100);\n+ // let (input_tx, input_rx) = tokio::sync::mpsc::channel::(100);\n+ //\n+ // // let input_loop_fut = input_loop(input_tx);\n+ // let input_tx_clone = input_tx.clone();\n+ // app.on_submit(move |m| {\n+ // debug!(\"sent: {:?}\", m);\n+ // input_tx_clone.blocking_send(m).unwrap();\n+ // });\n+ //\n+ // let topic = if args.topic.is_some() {\n+ // args.topic.clone()\n+ // } else {\n+ // Some(String::from(commit_id.to_string()))\n+ // };\n+ //\n+ // app.topic = topic.clone().unwrap();\n+ //\n+ // let topic = gossipsub::IdentTopic::new(format!(\"{}\", app.topic.clone()));\n+ //\n+ // global_rt().spawn(async move {\n+ // evt_loop(input_rx, peer_tx, topic).await.unwrap();\n+ // });\n+ //\n+ // // recv from peer\n+ // let mut tui_msg_adder = app.add_msg_fn();\n+ // global_rt().spawn(async move {\n+ // while let Some(m) = peer_rx.recv().await {\n+ // debug!(\"recv: {:?}\", m);\n+ // tui_msg_adder(m);\n+ // }\n+ // });\n+ //\n+ // // say hi\n+ // let input_tx_clone = input_tx.clone();\n+ // global_rt().spawn(async move {\n+ // tokio::time::sleep(Duration::from_millis(1000)).await;\n+ // input_tx_clone\n+ // .send(Msg::default().set_kind(MsgKind::Join))\n+ // .await\n+ // .unwrap();\n+ // });\n+ //\n+ // app.run()?;\n+ //\n+ // // say goodbye\n+ // input_tx.blocking_send(Msg::default().set_kind(MsgKind::Leave))?;\n+ // std::thread::sleep(Duration::from_millis(500));\n+ //\n Ok(())\n }\ndiff --git a/src/lib/sub_commands/fetch.rs b/src/lib/sub_commands/fetch.rs\nindex d6343357..2c05425c 100644\n--- a/src/lib/sub_commands/fetch.rs\n+++ b/src/lib/sub_commands/fetch.rs\n@@ -11,7 +11,7 @@ use crate::{\n repo_ref::get_repo_coordinates,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// address pointer to repo announcement\n #[arg(long, action)]\ndiff --git a/src/lib/sub_commands/login.rs b/src/lib/sub_commands/login.rs\nindex 78ea3a58..176a7043 100644\n--- a/src/lib/sub_commands/login.rs\n+++ b/src/lib/sub_commands/login.rs\n@@ -8,7 +8,7 @@ use crate::{\n login,\n };\n\n-#[derive(clap::Args)]\n+#[derive(clap::Args, Debug)]\n pub struct SubCommandArgs {\n /// don't fetch user metadata and relay list from relays\n #[arg(long, action)]\n","time":1746136255}

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f

Hello Worlds 33917193e2779326fe48646f07001920da59cfd4d500e976caa557527e212a6f