Improve events
Add known clients (cache) for leaving clients Add message to returned json object
This commit is contained in:
		
							parent
							
								
									f860fe3689
								
							
						
					
					
						commit
						ae411b6dcc
					
				
					 7 changed files with 117 additions and 24 deletions
				
			
		
							
								
								
									
										2
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							|  | @ -182,7 +182,7 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "teamspeak-query-lib" | ||||
| version = "0.1.2" | ||||
| version = "0.1.4" | ||||
| dependencies = [ | ||||
|  "clap", | ||||
|  "serde", | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| [package] | ||||
| name = "teamspeak-query-lib" | ||||
| version = "0.1.2" | ||||
| version = "0.1.4" | ||||
| edition = "2021" | ||||
| 
 | ||||
| [dependencies] | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| use telnet::Telnet; | ||||
| use crate::commands; | ||||
| use crate::models::{Event, EventType}; | ||||
| use crate::{commands, wrappers}; | ||||
| use crate::models::{Client, Event, EventType}; | ||||
| use crate::response::Response; | ||||
| 
 | ||||
| pub fn register_events(connection: &mut Telnet, events: Vec<EventType>) -> Result<(), String> { | ||||
|  | @ -12,10 +12,10 @@ pub fn register_events(connection: &mut Telnet, events: Vec<EventType>) -> Resul | |||
|     Ok(()) | ||||
| } | ||||
| 
 | ||||
| pub fn handle_event_response(connection: &mut Telnet, response: Response) { | ||||
| pub fn handle_event_response(connection: &mut Telnet, response: Response, known_clients: &mut Vec<Client>) { | ||||
|     if let Response::Event(event_type, params) = response { | ||||
| 
 | ||||
|         let event = Event::new(connection, event_type, params); | ||||
|         let event = Event::new(connection, event_type, params, &known_clients); | ||||
|         match serde_json::to_string(&event) { | ||||
|             Ok(json) => println!("{}", json), | ||||
|             Err(err) => { | ||||
|  | @ -24,13 +24,17 @@ pub fn handle_event_response(connection: &mut Telnet, response: Response) { | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if let Ok(new_clients) = wrappers::get_clients(connection) { | ||||
|             *known_clients = new_clients; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn loop_response_reader(connection: &mut Telnet) { | ||||
|     let mut known_clients = wrappers::get_clients(connection).unwrap_or_else(|_| Vec::new()); | ||||
|     loop { | ||||
|         match commands::read_response(connection, true, String::new()) { | ||||
|             Ok(response) => handle_event_response(connection, response), | ||||
|             Ok(response) => handle_event_response(connection, response, &mut known_clients), | ||||
|             Err(_) => { | ||||
|                 // print error?
 | ||||
|                 return; | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; | |||
| 
 | ||||
| use crate::parameter::{parameter_find, ParameterList}; | ||||
| 
 | ||||
| #[derive(Serialize, Deserialize, Debug)] | ||||
| #[derive(Serialize, Deserialize, Clone, Debug)] | ||||
| pub struct Client { | ||||
|     pub cid: i32, | ||||
|     pub clid: i32, | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| use std::fmt::{Display, Formatter}; | ||||
| use std::str::FromStr; | ||||
| 
 | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use serde::{Deserialize, Serialize, Serializer}; | ||||
| use serde::ser::SerializeStruct; | ||||
| use telnet::Telnet; | ||||
| 
 | ||||
| use crate::models::{Channel, Client}; | ||||
|  | @ -43,7 +44,7 @@ pub enum EventType { | |||
|     NotifyConnectStatusChange, | ||||
| } | ||||
| 
 | ||||
| #[derive(Serialize, Deserialize, Debug)] | ||||
| #[derive(Debug)] | ||||
| pub struct Event { | ||||
|     pub event_type: EventType, | ||||
|     pub params: ParameterList, | ||||
|  | @ -152,36 +153,58 @@ impl Display for EventType { | |||
| } | ||||
| 
 | ||||
| impl EventType { | ||||
| 
 | ||||
|     pub fn find_channel(&self, connection: &mut Telnet, params: &ParameterList, param_name: &str) -> Option<Channel> { | ||||
|         let id = parameter_find(params, param_name)? | ||||
|             .parse::<i32>().unwrap_or(0); | ||||
|         wrappers::find_channel(connection, "cid", &id.to_string(), true).unwrap().or(None) | ||||
|     } | ||||
|     pub fn get_channel(&self, connection: &mut Telnet, params: &ParameterList) -> Option<Channel> { | ||||
|         match self { | ||||
|             EventType::NotifyClientMoved => { | ||||
|                 let id = parameter_find(params, "ctid")? | ||||
|                     .parse::<i32>().unwrap_or(0); | ||||
|                 wrappers::find_channel(connection, "cid", &id.to_string(), true).unwrap().or(None) | ||||
|                 self.find_channel(connection, params, "ctid") | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_client(&self, connection: &mut Telnet, params: &ParameterList) -> Option<Client> { | ||||
|         match self { | ||||
|             EventType::NotifyClientMoved => { | ||||
|                 let id = parameter_find(params, "clid")? | ||||
|     pub fn find_client(&self, connection: &mut Telnet, params: &ParameterList, param_name: &str) -> Option<Client> { | ||||
|         let id = parameter_find(params, param_name)? | ||||
|             .parse::<i32>().unwrap_or(0); | ||||
|         wrappers::find_client(connection, "clid", &id.to_string(), true).unwrap().or(None) | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_client(&self, connection: &mut Telnet, params: &ParameterList) -> Option<Client> { | ||||
|         match self { | ||||
|             EventType::NotifyClientMoved => { | ||||
|                 self.find_client(connection, params, "clid") | ||||
|             } | ||||
|             EventType::NotifyClientEnterView => { | ||||
|                 Some(Client::from(params.clone())) | ||||
|             } | ||||
|             EventType::NotifyTextMessage => { | ||||
|                 self.find_client(connection, params, "invokerid") | ||||
|             } | ||||
|             EventType::NotifyClientPoke => { | ||||
|                 self.find_client(connection, params, "invokerid") | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Event { | ||||
|     pub fn new(connection: &mut Telnet, event_type: EventType, params: ParameterList) -> Event { | ||||
|     pub fn new(connection: &mut Telnet, event_type: EventType, params: ParameterList, known_clients: &[Client]) -> Event { | ||||
|         let channel = event_type.get_channel(connection, ¶ms); | ||||
|         let client = event_type.get_client(connection, ¶ms); | ||||
|         let mut client = event_type.get_client(connection, ¶ms); | ||||
| 
 | ||||
|         if client.is_none() { | ||||
|             let id = parameter_find(¶ms, "clid") | ||||
|                 .unwrap_or_else(|| String::from("0")) | ||||
|                 .parse::<i32>().unwrap_or(0); | ||||
|             let client_id = id.to_string(); | ||||
|             client = known_clients.iter().find(|c| c.clid.to_string() == client_id).cloned(); | ||||
|         } | ||||
| 
 | ||||
|         Event { | ||||
|             event_type, | ||||
|  | @ -190,4 +213,70 @@ impl Event { | |||
|             client, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_client_name(&self) -> String { | ||||
|         match &self.client { | ||||
|             Some(client) => client.client_nickname.clone(), | ||||
|             None => String::from("UNKNOWN"), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_channel_name(&self) -> String { | ||||
|         match &self.channel { | ||||
|             Some(channel) => channel.channel_name.clone(), | ||||
|             None => String::from("UNKNOWN"), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_event_msg(&self) -> String { | ||||
|         parameter_find(&self.params, "msg").unwrap_or_else(|| String::from("")) | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_message(&self) -> String { | ||||
|         match &self.event_type { | ||||
|             EventType::NotifyClientPoke => { | ||||
|                 format!("{}: {}", | ||||
|                         self.get_client_name(), | ||||
|                         self.get_event_msg() | ||||
|                 ) | ||||
|             } | ||||
|             EventType::NotifyTextMessage => { | ||||
|                 format!("{}: {}", | ||||
|                         self.get_client_name(), | ||||
|                         self.get_event_msg() | ||||
|                 ) | ||||
|             } | ||||
|             EventType::NotifyClientMoved => { | ||||
|                 format!("{} joined {}", | ||||
|                     self.get_client_name(), | ||||
|                     self.get_channel_name() | ||||
|                 ) | ||||
|             } | ||||
|             EventType::NotifyClientLeftView => { | ||||
|                 format!("{} left", | ||||
|                     self.get_client_name() | ||||
|                 ) | ||||
|             } | ||||
|             EventType::NotifyClientEnterView => { | ||||
|                 format!("{} connected", | ||||
|                     self.get_client_name() | ||||
|                 ) | ||||
|             } | ||||
|             _ => String::from(""), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Serialize for Event { | ||||
|     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||
|         where | ||||
|             S: Serializer, | ||||
|     { | ||||
|         let mut x = serializer.serialize_struct("Event", 4)?; | ||||
|         x.serialize_field("type", &self.event_type)?; | ||||
|         x.serialize_field("channel", &self.channel)?; | ||||
|         x.serialize_field("client", &self.client)?; | ||||
|         x.serialize_field("message", &self.get_message())?; | ||||
|         x.end() | ||||
|     } | ||||
| } | ||||
|  | @ -44,7 +44,7 @@ pub fn parameter_parse(params_str: &str) -> ParameterList { | |||
| 
 | ||||
|     let mut response_params = ParameterList::new(); | ||||
|     parts.iter().for_each(|part| { | ||||
|         let (key, value) = part.split_once('=').unwrap_or((part, "1")); | ||||
|         let (key, value) = part.split_once('=').unwrap_or((part, "")); | ||||
|         response_params.insert(key.to_string(), decode_value(value)); | ||||
|     }); | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										10
									
								
								ts-control
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								ts-control
									
										
									
									
									
								
							|  | @ -9,7 +9,7 @@ not away | |||
| back | ||||
| message | ||||
| message-user | ||||
| events-move" | ||||
| events" | ||||
| 
 | ||||
| _ts_control_get_entity() { | ||||
| 	entity=$(_ts_control_single_or_dmenu "$(teamspeak-query-lib "$1s")" "$2") | ||||
|  | @ -98,8 +98,8 @@ case $action in | |||
| 		message=$(_ts_control_get_message "$3") | ||||
| 		teamspeak-query-lib message --strict-client --client "$user" "$message" | ||||
| 		;; | ||||
| 	"events-move") | ||||
| 		teamspeak-query-lib events NotifyClientMoved NotifyClientEnterView \ | ||||
| 			| jq -r --unbuffered '.client.client_nickname + " joined " + .channel.channel_name // "the server"' \ | ||||
| 			| tee >(xargs -I{} notify-send "TS3 movement" "{}") | ||||
| 	"events") | ||||
| 		teamspeak-query-lib events NotifyClientMoved NotifyClientEnterView NotifyClientLeftView NotifyTextMessage NotifyClientPoke \ | ||||
| 			| jq -r --unbuffered '.message' \ | ||||
| 			| tee >(xargs -I{} notify-send "TS3 Event" "{}") | ||||
| esac | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue