Refactor and add message command

This commit is contained in:
Tobias Reisinger 2023-11-26 22:30:59 +01:00
parent e87bed00a2
commit fa959136be
Signed by: serguzim
GPG key ID: 13AD60C237A28DFE
8 changed files with 370 additions and 263 deletions

View file

@ -4,7 +4,8 @@ use telnet::Telnet;
use crate::parameter::{Parameter, ParameterList};
use crate::response::channel::ResponseChannel;
use crate::response::client::ResponseClient;
use crate::utils;
use crate::utils::SendTextMessageTarget;
use crate::wrappers;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
@ -19,6 +20,7 @@ pub enum Commands {
Channels(ChannelsArgs),
Clients,
Fetch(FetchArgs),
Message(MessageArgs),
Move(MoveArgs),
Update(UpdateArgs),
}
@ -41,6 +43,17 @@ pub struct FetchArgs {
client: Option<String>,
}
#[derive(Args)]
pub struct MessageArgs {
#[arg(long)]
strict_client: bool,
#[arg(long)]
client: Option<String>,
#[arg(long)]
server: bool,
pub message: String,
}
#[derive(Args)]
pub struct MoveArgs {
#[arg(long)]
@ -76,31 +89,46 @@ impl FetchArgs {
pub fn channel(&self, connection: &mut Telnet) -> Result<Option<ResponseChannel>, String> {
if let Some(channel) = &self.channel {
utils::find_channel(connection, channel, self.strict_channel)
wrappers::find_channel(connection, channel, self.strict_channel)
} else {
Err("No channel specified.".to_string())
}
}
pub fn client(&self, connection: &mut Telnet) -> Result<Option<ResponseClient>, String> {
if let Some(client) = &self.client {
utils::find_client(connection, client, self.strict_client)
wrappers::find_client(connection, client, self.strict_client)
} else {
Err("No client specified.".to_string())
}
}
}
impl MessageArgs {
pub fn target(&self, connection: &mut Telnet) -> Result<SendTextMessageTarget, String> {
if self.server {
Ok(SendTextMessageTarget::Server)
} else if let Some(client) = &self.client {
if let Some(client) = wrappers::find_client(connection, client, self.strict_client)? {
return Ok(SendTextMessageTarget::Client(client.cid));
}
return Err("Could not find client.".to_string());
} else {
Ok(SendTextMessageTarget::Channel)
}
}
}
impl MoveArgs {
pub fn channel(&self, connection: &mut Telnet) -> Result<Option<ResponseChannel>, String> {
utils::find_channel(connection, &self.channel, self.strict_channel)
wrappers::find_channel(connection, &self.channel, self.strict_channel)
}
pub fn client(&self, connection: &mut Telnet) -> Result<Option<ResponseClient>, String> {
match &self.client {
Some(client) => {
utils::find_client(connection, client, self.strict_client)
wrappers::find_client(connection, client, self.strict_client)
}
None => {
match utils::find_self(connection) {
match wrappers::find_self(connection) {
Ok(client) => Ok(Some(client)),
Err(msg) => Err(msg)
}
@ -114,24 +142,22 @@ impl UpdateArgs {
let mut params: ParameterList = Vec::new();
if let Some(name) = &self.name {
params.push(Parameter::new(String::from("client_nickname"), name.clone()));
params.push(Parameter::new("client_nickname", name));
}
if let Some(away) = &self.away {
params.push(Parameter::new(String::from("client_away_message"), away.clone()));
params.push(Parameter::new(String::from("client_away"), String::from("1")));
params.push(Parameter::new("client_away_message", away));
params.push(Parameter::new("client_away", "1"));
}
if self.back {
params.push(Parameter::new(String::from("client_away"), String::from("0")));
params.push(Parameter::new("client_away", "0"));
}
if let Some(microphone) = self.microphone {
let muted = u8::from(!microphone).to_string();
params.push(Parameter::new(String::from("client_input_muted"), muted));
params.push(Parameter::new("client_input_muted", &u8::from(!microphone).to_string()));
}
if let Some(speakers) = self.speakers {
let muted = u8::from(!speakers).to_string();
params.push(Parameter::new(String::from("client_output_muted"), muted));
params.push(Parameter::new("client_output_muted", &u8::from(!speakers).to_string()));
}
params

View file

@ -1,7 +1,8 @@
use crate::utils::SendTextMessageTarget;
use telnet::Event::Data;
use telnet::Telnet;
use crate::parameter::ParameterList;
use crate::parameter::{Parameter, ParameterList};
use crate::response::Response;
fn to_single_response(resp: Response) -> Response {
@ -41,6 +42,7 @@ fn read_response_buffer(connection: &mut Telnet, buffer: &mut String) -> Result<
}
fn send_command(connection: &mut Telnet, command: &str, skip_ok: bool) -> Result<Response, String> {
let command = format!("{}\n\r", command);
connection.write(command.as_bytes()).map_err(|_| "Failed to write to Teamspeak.")?;
read_response(connection, skip_ok, String::new())
@ -68,40 +70,40 @@ fn read_response(connection: &mut Telnet, skip_ok: bool, mut buffer: String) ->
}
pub fn login(connection: &mut Telnet, apikey: &str) -> Result<Response, String> {
send_command(connection, &format!("auth apikey={}\n", apikey), false)
send_command(connection, &format!("auth apikey={}", apikey), false)
}
#[allow(dead_code)]
pub fn set_name(connection: &mut Telnet, name: &str) -> Result<Response, String> {
send_command(connection, &format!("clientupdate client_nickname={}\n", name), true)
send_command(connection, &format!("clientupdate client_nickname={}", name), true)
}
pub fn channellist(connection: &mut Telnet) -> Result<Response, String> {
send_command(connection, "channellist\n", true)
send_command(connection, "channellist", true)
}
pub fn clientlist(connection: &mut Telnet) -> Result<Response, String> {
send_command(connection, "clientlist\n", true)
send_command(connection, "clientlist", true)
}
pub fn whoami(connection: &mut Telnet) -> Result<Response, String> {
send_command(connection, "whoami\n", true).map(to_single_response)
send_command(connection, "whoami", true).map(to_single_response)
}
pub fn clientmove(connection: &mut Telnet, cid: &i32, clid_list: Vec<&i32>) -> Result<Response, String> {
let clid_str = clid_list
.iter()
.map(|clid| format!("clid={}", clid))
.collect::<Vec<String>>()
.join("|");
send_command(connection, &format!("clientmove cid={} {}\n", cid, clid_str), false)
let clid_param_list = clid_list
.into_iter()
.map(|clid| Parameter::new("clid", &clid.to_string()))
.collect::<Vec<Parameter>>();
let clid_str = Parameter::list_to_string_sep(clid_param_list, "|");
send_command(connection, &format!("clientmove cid={} {}", cid, clid_str), false)
}
pub fn clientupdate(connection: &mut Telnet, parameters: &ParameterList) -> Result<Response, String> {
let parameters_str = parameters
.iter()
.map(|param| format!("{}={}", param.name, param.value))
.collect::<Vec<String>>()
.join(" ");
send_command(connection, &format!("clientupdate {}\n", parameters_str), false)
}
pub fn clientupdate(connection: &mut Telnet, parameters: ParameterList) -> Result<Response, String> {
let parameters_str = Parameter::list_to_string(parameters);
send_command(connection, &format!("clientupdate {}", parameters_str), false)
}
pub fn sendtextmessage(connection: &mut Telnet, target: SendTextMessageTarget, msg: String) -> Result<Response, String> {
let msg = String::from(Parameter::new("msg", &msg));
send_command(connection, &format!("sendtextmessage {} {}", msg, String::from(target)), false) }

View file

@ -7,10 +7,11 @@ use crate::response::channel::ResponseChannel;
use crate::response::client::ResponseClient;
mod response;
mod utils;
mod wrappers;
mod commands;
mod parameter;
mod cli;
mod utils;
fn channel_or_exit(channel_res: Result<Option<ResponseChannel>, String>) -> ResponseChannel {
channel_res.unwrap_or_else(|err| {
@ -44,14 +45,14 @@ fn main() {
}
let mut connection = connection.unwrap();
utils::skip_welcome(&mut connection);
utils::login(&mut connection);
wrappers::skip_welcome(&mut connection);
wrappers::login(&mut connection);
// You can check for the existence of subcommands, and if found use their
// matches just as you would the top level cmd
match &cli {
match cli {
Commands::Channels(args) => {
match utils::get_channels(&mut connection, args.spacers) {
match wrappers::get_channels(&mut connection, args.spacers) {
Ok(channels) => {
for channel in channels {
println!("{}", channel.channel_name);
@ -65,7 +66,7 @@ fn main() {
}
Commands::Clients => {
match utils::get_clients(&mut connection) {
match wrappers::get_clients(&mut connection) {
Ok(clients) => {
for client in clients {
println!("{}", client.client_nickname);
@ -91,7 +92,7 @@ fn main() {
if args.want_client() {
let client = client_or_exit(args.client(&mut connection));
match utils::fetch_client(&mut connection, &[client]) {
match wrappers::fetch_client(&mut connection, &[client]) {
Ok(_) => println!("Successfully fetched client."),
Err(msg) => {
println!("Failed to fetch client: {}", msg);
@ -103,7 +104,7 @@ fn main() {
if args.want_channel() {
let channel = channel_or_exit(args.channel(&mut connection));
match utils::fetch_channel(&mut connection, channel) {
match wrappers::fetch_channel(&mut connection, channel) {
Ok(_) => println!("Successfully fetched channel."),
Err(msg) => {
println!("Failed to fetch channel: {}", msg);
@ -113,11 +114,26 @@ fn main() {
}
}
Commands::Message(args) => {
let target = args.target(&mut connection).unwrap_or_else(|err| {
println!("Failed to get message target: {}", err);
exit(1);
});
match wrappers::send_text_message(&mut connection, target, args.message) {
Ok(_) => println!("Successfully sent message."),
Err(msg) => {
println!("Failed to send message: {}", msg);
exit(1);
}
}
}
Commands::Move(args) => {
let channel = channel_or_exit(args.channel(&mut connection));
let client = client_or_exit(args.client(&mut connection));
match utils::move_client(&mut connection, &channel, &[client]) {
match wrappers::move_client(&mut connection, &channel, &[client]) {
Ok(resp) => println!("Successfully moved client: {}", resp),
Err(msg) => {
println!("Failed to move client: {}", msg);
@ -127,7 +143,7 @@ fn main() {
}
Commands::Update(args) => {
match utils::update_client(&mut connection, &args.to_parameter_list()) {
match wrappers::update_client(&mut connection, args.to_parameter_list()) {
Ok(_) => println!("Successfully updated client."),
Err(msg) => {
println!("Failed to update client: {}", msg);

View file

@ -1,4 +1,5 @@
use std::fmt::{Debug, Display, Formatter};
use crate::utils::{decode_value, encode_value};
#[derive(Clone)]
pub struct Parameter {
@ -49,19 +50,15 @@ pub fn parameter_parse(params_str: &str) -> ParameterList {
impl From<(&str, &str)> for Parameter {
fn from(param: (&str, &str)) -> Parameter {
Parameter::new(String::from(param.0), String::from(param.1))
Parameter::new(param.0, param.1)
}
}
impl Parameter {
pub fn new(name: String, value: String) -> Parameter {
let value = value
.replace("\\s", " ")
.replace("\\p", "|");
pub fn new(name: &str, value: &str) -> Parameter {
Parameter {
name,
value,
name: String::from(name),
value: decode_value(value)
}
}
@ -81,6 +78,22 @@ impl Parameter {
pub fn to_i32(&self, default: i32) -> i32 {
self.value.parse::<i32>().unwrap_or(default)
}
pub fn list_to_string(parameter_list: ParameterList) -> String {
parameter_list
.into_iter()
.map(String::from)
.collect::<Vec<String>>()
.join(" ")
}
pub fn list_to_string_sep(parameter_list: ParameterList, sep: &str) -> String {
parameter_list
.into_iter()
.map(String::from)
.collect::<Vec<String>>()
.join(sep)
}
}
impl Display for Parameter {
@ -97,6 +110,12 @@ impl Debug for Parameter {
impl Default for Parameter {
fn default() -> Self {
Parameter::new(String::from(""), String::from(""))
Parameter::new("", "")
}
}
impl From<Parameter> for String {
fn from(value: Parameter) -> Self {
format!("{}={}", value.name, encode_value(&value.value))
}
}

View file

@ -93,10 +93,10 @@ impl ResponseError {
fn create_error(params: &Vec<Parameter>) -> ResponseError {
ResponseError {
id: parameter_find(params, "id")
.unwrap_or_else(|| Parameter::new(String::from("id"), String::from("-1")))
.unwrap_or_else(|| Parameter::new("id", "-1"))
.to_i32(-1),
msg: parameter_find(params, "msg")
.unwrap_or_else(|| Parameter::new(String::from("msg"), String::from("Unknown error.")))
.unwrap_or_else(|| Parameter::new("msg", "Unknown error."))
.value,
}
}

View file

@ -1,208 +1,39 @@
use std::process::exit;
use std::time::Duration;
use crate::parameter::Parameter;
use telnet::Event::TimedOut;
use telnet::Telnet;
pub fn decode_value(value: &str) -> String {
value
.replace("\\s", " ")
.replace("\\p", "|")
}
use crate::{commands, parameter};
use crate::parameter::{parameter_list_find_all, ParameterList};
use crate::response::channel::ResponseChannel;
use crate::response::client::ResponseClient;
use crate::response::Response;
pub fn encode_value(value: &str) -> String {
value
.replace(' ', "\\s")
.replace('|', "\\p")
}
pub fn skip_welcome(connection: &mut Telnet) {
loop {
let event_result = connection.read_timeout(Duration::from_millis(100));
match event_result {
Ok(event) => {
if let TimedOut = event {
break;
}
}
Err(_) => println!("Failed to read from Teamspeak."),
}
pub enum SendTextMessageTarget {
Client(i32),
Channel,
Server,
}
impl From<SendTextMessageTarget> for String {
fn from(value: SendTextMessageTarget) -> Self {
let target_mode = match value {
SendTextMessageTarget::Client(_) => "1",
SendTextMessageTarget::Channel => "2",
SendTextMessageTarget::Server => "3",
};
let target = match value {
SendTextMessageTarget::Client(id) => id.to_string(),
_ => String::from("0"),
};
Parameter::list_to_string(vec![
Parameter::new("targetmode", target_mode),
Parameter::new("target", &target)
])
}
}
pub fn login(connection: &mut Telnet) {
// read api key from environment variable
let apikey = std::env::var("TS3_CLIENT_API_KEY").unwrap_or_else(|_| {
println!("No API key found in environment variable TS3_CLIENT_API_KEY.");
exit(1);
});
match commands::login(connection, &apikey) {
Ok(_) => {}
Err(msg) => {
println!("Failed to authenticate with Teamspeak: {}", msg);
exit(1);
}
}
}
pub fn get_channels(connection: &mut Telnet, spacers: bool) -> Result<Vec<ResponseChannel>, String> {
match commands::channellist(connection) {
Ok(response) => {
match response {
Response::DataList(parameter_lists) => {
let channels: Vec<ResponseChannel> = parameter_lists.iter()
.map(|params| ResponseChannel::from(params.clone()))
.collect();
let mut channels = ResponseChannel::sort_list(channels);
if !spacers {
channels.retain(|c| !c.is_spacer());
}
Ok(channels)
}
_ => Err(String::from("Received unexpected response from Teamspeak."))
}
}
Err(msg) => Err(msg)
}
}
pub fn find_channel(connection: &mut Telnet, name: &str, strict: bool) -> Result<Option<ResponseChannel>, String> {
match commands::channellist(connection) {
Ok(response) => {
match response {
Response::DataList(parameter_lists) => {
match parameter::parameter_list_find(&parameter_lists, "channel_name", name, strict) {
Some(params) => {
Ok(Some(ResponseChannel::from(params)))
}
None => {
Ok(None)
}
}
}
_ => Err(String::from("Received unexpected response from Teamspeak."))
}
}
Err(msg) => Err(msg)
}
}
pub fn get_clients(connection: &mut Telnet) -> Result<Vec<ResponseClient>, String> {
match commands::clientlist(connection) {
Ok(response) => {
match response {
Response::DataList(parameter_lists) => {
let mut clients: Vec<ResponseClient> = parameter_lists.iter()
.map(|params| ResponseClient::from(params.clone()))
.collect();
clients.sort_by(|a, b| a.client_nickname.cmp(&b.client_nickname));
Ok(clients)
}
_ => Err(String::from("Received unexpected response from Teamspeak."))
}
}
Err(msg) => Err(msg)
}
}
pub fn find_client(connection: &mut Telnet, name: &str, strict: bool) -> Result<Option<ResponseClient>, String> {
match commands::clientlist(connection) {
Ok(response) => {
match response {
Response::DataList(parameter_lists) => {
match parameter::parameter_list_find(&parameter_lists, "client_nickname", name, strict) {
Some(params) => {
Ok(Some(ResponseClient::from(params)))
}
None => {
Ok(None)
}
}
}
_ => Err(String::from("Received unexpected response from Teamspeak."))
}
}
Err(msg) => Err(msg)
}
}
pub fn get_channel_clients(connection: &mut Telnet, channel: &ResponseChannel) -> Result<Vec<ResponseClient>, String> {
match commands::clientlist(connection) {
Ok(response) => {
match response {
Response::DataList(parameter_lists) => {
let mut clients: Vec<ResponseClient> = Vec::new();
for client_params in parameter_list_find_all(&parameter_lists, "cid", &channel.cid.to_string(), true) {
clients.push(ResponseClient::from(client_params));
}
Ok(clients)
}
_ => Err(String::from("Received unexpected response from Teamspeak."))
}
}
Err(msg) => Err(msg)
}
}
fn get_self_clid(connection: &mut Telnet) -> Result<String, String> {
match commands::whoami(connection) {
Ok(response) => {
match response {
Response::Data(params) => {
match parameter::parameter_find(&params, "clid") {
None => Err(String::from("Could not find clid in response from Teamspeak.")),
Some(param) => Ok(param.value)
}
}
_ => Err(String::from("Received unexpected response from Teamspeak for whoami."))
}
}
Err(msg) => Err(msg)
}
}
pub fn find_self(connection: &mut Telnet) -> Result<ResponseClient, String> {
let clid = get_self_clid(connection)?;
match commands::clientlist(connection) {
Ok(response) => {
match response {
Response::DataList(parameter_lists) => {
match parameter::parameter_list_find(&parameter_lists, "clid", &clid, false) {
Some(params) => {
Ok(ResponseClient::from(params))
}
None => {
Err(String::from("Could not find self in response from Teamspeak."))
}
}
}
_ => Err(String::from("Received unexpected response from Teamspeak for clientlist."))
}
}
Err(msg) => Err(msg)
}
}
pub fn fetch_client(connection: &mut Telnet, clients: &[ResponseClient]) -> Result<Response, String> {
let cid = find_self(connection)?.cid;
let clid_list: Vec<&i32> = clients.iter().map(|c| &c.clid).collect();
commands::clientmove(connection, &cid, clid_list)
}
pub fn fetch_channel(connection: &mut Telnet, channel: ResponseChannel) -> Result<Response, String> {
let cid = find_self(connection)?.cid;
let clients = get_channel_clients(connection, &channel)?;
let clid_list: Vec<&i32> = clients.iter().map(|c| &c.clid).collect();
commands::clientmove(connection, &cid, clid_list)
}
pub fn move_client(connection: &mut Telnet, channel: &ResponseChannel, clients: &[ResponseClient]) -> Result<Response, String> {
let clid_list: Vec<&i32> = clients.iter().map(|c| &c.clid).collect();
commands::clientmove(connection, &channel.cid, clid_list)
}
pub fn update_client(connection: &mut Telnet, parameters: &ParameterList) -> Result<Response, String> {
commands::clientupdate(connection, parameters)
}

213
src/wrappers.rs Normal file
View file

@ -0,0 +1,213 @@
use std::process::exit;
use std::time::Duration;
use telnet::Event::TimedOut;
use telnet::Telnet;
use crate::{commands, parameter};
use crate::parameter::{parameter_list_find_all, ParameterList};
use crate::response::channel::ResponseChannel;
use crate::response::client::ResponseClient;
use crate::response::Response;
use crate::utils::SendTextMessageTarget;
pub fn skip_welcome(connection: &mut Telnet) {
loop {
let event_result = connection.read_timeout(Duration::from_millis(100));
match event_result {
Ok(event) => {
if let TimedOut = event {
break;
}
}
Err(_) => println!("Failed to read from Teamspeak."),
}
}
}
pub fn login(connection: &mut Telnet) {
// read api key from environment variable
let apikey = std::env::var("TS3_CLIENT_API_KEY").unwrap_or_else(|_| {
println!("No API key found in environment variable TS3_CLIENT_API_KEY.");
exit(1);
});
match commands::login(connection, &apikey) {
Ok(_) => {}
Err(msg) => {
println!("Failed to authenticate with Teamspeak: {}", msg);
exit(1);
}
}
}
pub fn get_channels(connection: &mut Telnet, spacers: bool) -> Result<Vec<ResponseChannel>, String> {
match commands::channellist(connection) {
Ok(response) => {
match response {
Response::DataList(parameter_lists) => {
let channels: Vec<ResponseChannel> = parameter_lists.iter()
.map(|params| ResponseChannel::from(params.clone()))
.collect();
let mut channels = ResponseChannel::sort_list(channels);
if !spacers {
channels.retain(|c| !c.is_spacer());
}
Ok(channels)
}
_ => Err(String::from("Received unexpected response from Teamspeak."))
}
}
Err(msg) => Err(msg)
}
}
pub fn find_channel(connection: &mut Telnet, name: &str, strict: bool) -> Result<Option<ResponseChannel>, String> {
match commands::channellist(connection) {
Ok(response) => {
match response {
Response::DataList(parameter_lists) => {
match parameter::parameter_list_find(&parameter_lists, "channel_name", name, strict) {
Some(params) => {
Ok(Some(ResponseChannel::from(params)))
}
None => {
Ok(None)
}
}
}
_ => Err(String::from("Received unexpected response from Teamspeak."))
}
}
Err(msg) => Err(msg)
}
}
pub fn get_clients(connection: &mut Telnet) -> Result<Vec<ResponseClient>, String> {
match commands::clientlist(connection) {
Ok(response) => {
match response {
Response::DataList(parameter_lists) => {
let mut clients: Vec<ResponseClient> = parameter_lists.iter()
.map(|params| ResponseClient::from(params.clone()))
.collect();
clients.sort_by(|a, b| a.client_nickname.cmp(&b.client_nickname));
Ok(clients)
}
_ => Err(String::from("Received unexpected response from Teamspeak."))
}
}
Err(msg) => Err(msg)
}
}
pub fn find_client(connection: &mut Telnet, name: &str, strict: bool) -> Result<Option<ResponseClient>, String> {
match commands::clientlist(connection) {
Ok(response) => {
match response {
Response::DataList(parameter_lists) => {
match parameter::parameter_list_find(&parameter_lists, "client_nickname", name, strict) {
Some(params) => {
Ok(Some(ResponseClient::from(params)))
}
None => {
Ok(None)
}
}
}
_ => Err(String::from("Received unexpected response from Teamspeak."))
}
}
Err(msg) => Err(msg)
}
}
pub fn get_channel_clients(connection: &mut Telnet, channel: &ResponseChannel) -> Result<Vec<ResponseClient>, String> {
match commands::clientlist(connection) {
Ok(response) => {
match response {
Response::DataList(parameter_lists) => {
let mut clients: Vec<ResponseClient> = Vec::new();
for client_params in parameter_list_find_all(&parameter_lists, "cid", &channel.cid.to_string(), true) {
clients.push(ResponseClient::from(client_params));
}
Ok(clients)
}
_ => Err(String::from("Received unexpected response from Teamspeak."))
}
}
Err(msg) => Err(msg)
}
}
fn get_self_clid(connection: &mut Telnet) -> Result<String, String> {
match commands::whoami(connection) {
Ok(response) => {
match response {
Response::Data(params) => {
match parameter::parameter_find(&params, "clid") {
None => Err(String::from("Could not find clid in response from Teamspeak.")),
Some(param) => Ok(param.value)
}
}
_ => Err(String::from("Received unexpected response from Teamspeak for whoami."))
}
}
Err(msg) => Err(msg)
}
}
pub fn find_self(connection: &mut Telnet) -> Result<ResponseClient, String> {
let clid = get_self_clid(connection)?;
match commands::clientlist(connection) {
Ok(response) => {
match response {
Response::DataList(parameter_lists) => {
match parameter::parameter_list_find(&parameter_lists, "clid", &clid, false) {
Some(params) => {
Ok(ResponseClient::from(params))
}
None => {
Err(String::from("Could not find self in response from Teamspeak."))
}
}
}
_ => Err(String::from("Received unexpected response from Teamspeak for clientlist."))
}
}
Err(msg) => Err(msg)
}
}
pub fn fetch_client(connection: &mut Telnet, clients: &[ResponseClient]) -> Result<Response, String> {
let cid = find_self(connection)?.cid;
let clid_list: Vec<&i32> = clients.iter().map(|c| &c.clid).collect();
commands::clientmove(connection, &cid, clid_list)
}
pub fn fetch_channel(connection: &mut Telnet, channel: ResponseChannel) -> Result<Response, String> {
let cid = find_self(connection)?.cid;
let clients = get_channel_clients(connection, &channel)?;
let clid_list: Vec<&i32> = clients.iter().map(|c| &c.clid).collect();
commands::clientmove(connection, &cid, clid_list)
}
pub fn move_client(connection: &mut Telnet, channel: &ResponseChannel, clients: &[ResponseClient]) -> Result<Response, String> {
let clid_list: Vec<&i32> = clients.iter().map(|c| &c.clid).collect();
commands::clientmove(connection, &channel.cid, clid_list)
}
pub fn update_client(connection: &mut Telnet, parameters: ParameterList) -> Result<Response, String> {
commands::clientupdate(connection, parameters)
}
pub fn send_text_message(connection: &mut Telnet, target: SendTextMessageTarget, msg: String) -> Result<Response, String> {
commands::sendtextmessage(connection, target, msg)
}

View file

@ -9,7 +9,7 @@ back"
action=$(echo "$actions" | $DMENU)
ts_control_move_self() {
_ts_control_move_self() {
channel=$(teamspeak-query-lib channels | $DMENU)
if [ -z "$channel" ]; then
return 1
@ -18,7 +18,7 @@ ts_control_move_self() {
return 0
}
ts_control_fetch() {
_ts_control_fetch() {
target=$(teamspeak-query-lib "$1s" | $DMENU)
if [ -z "$target" ]; then
exit 1
@ -28,13 +28,13 @@ ts_control_fetch() {
case $action in
"move")
ts_control_move_self
_ts_control_move_self
;;
"fetch-client")
ts_control_fetch client
_ts_control_fetch client
;;
"fetch-channel")
ts_control_fetch channel
_ts_control_fetch channel
;;
"not away")
teamspeak-query-lib move "Not Away From Keyboard"