From e8502779f02f3d8a9648ea8e7fa6c64de6214d77 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 19 Jul 2025 16:36:51 +0200 Subject: [PATCH] zmiany --- Cargo.toml | 4 +-- Dockerfile | 3 +- src/config.rs | 3 +- src/main.rs | 69 +++++++++++++++++++++++++++------------------ src/rrd.rs | 12 ++++---- src/ts3.rs | 33 +++++++++++++++------- templates/base.html | 2 +- 7 files changed, 78 insertions(+), 48 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0f448d6..2815d50 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,8 +11,8 @@ rrd = "0.1" # Zakładam dostępność; dostosuj jeśli potrzeba rand = "0.8" env_logger = "0.10" log = "0.4" -serde_teamspeak_querystring = "0.3" # Do parsowania zapytań TS3 +serde-teamspeak-querystring = "0.3" # Do parsowania zapytań TS3 askama = "0.10" # Dla szablonów HTML askama_derive = "0.10" chrono = "0.4" -actix-files = "0.6" \ No newline at end of file +actix-files = "0.6" diff --git a/Dockerfile b/Dockerfile index 2bf83b0..e041fb1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,6 @@ -FROM rust:1.70 AS builder +FROM rust:1.88 AS builder WORKDIR /app +RUN apt-get update && apt-get install -y libclang-dev librrd-dev COPY . . RUN cargo build --release diff --git a/src/config.rs b/src/config.rs index 18abb45..6dd65a5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,6 @@ use std::env; +#[derive(Clone)] pub struct Config { pub ts3_server: String, pub ts3_query_port: u16, @@ -7,7 +8,7 @@ pub struct Config { pub ts3_query_pass: String, pub rrd_file: String, pub rrd_update_interval: u64, - // Dodaj inne pola z config.example.py[2] + // Dodaj inne pola z config.example.py[2], np. channel_admin_group: u32 } impl Config { diff --git a/src/main.rs b/src/main.rs index 9a6b00c..8d70876 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,12 @@ use actix_web::{web, App, HttpServer, HttpResponse}; use askama::Template; -use chrono::prelude::*; +use chrono::{Utc, Datelike}; use tokio::time::{self, Duration}; use actix_files as fs; use serde::Deserialize; use crate::config::Config; -use crate::ts3::{get_ts3_connection, create_channel}; +use crate::ts3::{get_ts3_connection, create_channel, get_client_info}; use crate::rrd::{update_rrd_stats, generate_graphs}; mod config; @@ -26,18 +26,18 @@ struct CreateTemplate<'a> { ts3_server: &'a str, ts3_server_port: u16, client_ip: &'a str, - client_uuid: Option<&'a str>, - now: DateTime, - flash_message: Option, + client_uuid: &'a str, + year: i32, + flash_message: Option<&'a str>, } #[derive(Template)] #[template(path = "stats.html")] -struct StatsTemplate { - graphs: Vec, - last_update: String, - server_name: String, - now: DateTime, +struct StatsTemplate<'a> { + graphs: &'a [Graph], + last_update: &'a str, + server_name: &'a str, + year: i32, } struct Graph { @@ -47,45 +47,61 @@ struct Graph { async fn create_handler(data: web::Json) -> HttpResponse { let config = Config::load(); - // Logika tworzenia kanału (uproszczona; połącz z TS3) let mut stream = match get_ts3_connection(&config) { Ok(s) => s, Err(e) => { return HttpResponse::InternalServerError().body(format!("Błąd połączenia: {}", e)); } }; - let result = create_channel(&mut stream, &data.channel_name, &data.channel_topic, &data.channel_password); - let flash = match result { - Ok(_) => Some("Kanał utworzony pomyślnie".to_string()), - Err(e) => Some(format!("Błąd: {}", e)), + + // Pobierz client_info jak w app.py[1] + let client_info = get_client_info(&mut stream, "127.0.0.1"); + let (client_uuid, client_dbid, client_clid) = match &client_info { + Some(info) => (info.uid.as_str(), info.dbid, info.clid), + None => ("Brak UUID", 0, 0), }; + let result = create_channel( + &mut stream, + &data.channel_name, + &data.channel_topic, + &data.channel_password, + client_dbid, + client_clid, + ); + let flash_message = match result { + Ok(_) => Some("Kanał utworzony pomyślnie"), + Err(_e) => Some("Błąd tworzenia kanału"), + }; + + let now = Utc::now(); let template = CreateTemplate { ts3_server: &config.ts3_server, - ts3_server_port: config.ts3_query_port, // Dostosuj jeśli potrzeba - client_ip: "127.0.0.1", // Pobierz z request (np. req.connection_info().realip_remote_addr()) - client_uuid: Some("example-uuid"), - now: Utc::now(), - flash_message: flash, + ts3_server_port: config.ts3_query_port, + client_ip: "127.0.0.1", + client_uuid, + year: now.year(), + flash_message, }; HttpResponse::Ok().content_type("text/html").body(template.render().unwrap()) } async fn stats_handler() -> HttpResponse { let config = Config::load(); - // Generuj wykresy (uproszczone) generate_graphs(&config); - let graphs = vec![ + let graphs = [ Graph { file: "hour.gif".to_string(), title: "Ostatnie 12 godzin".to_string() }, Graph { file: "day.gif".to_string(), title: "Ostatnie 24 godziny".to_string() }, Graph { file: "72h.gif".to_string(), title: "Ostatnie 72 godziny".to_string() }, Graph { file: "week.gif".to_string(), title: "Ostatni tydzień".to_string() }, ]; + let now = Utc::now(); + let last_update = now.format("%Y-%m-%d %H:%M:%S").to_string(); let template = StatsTemplate { - graphs, - last_update: Utc::now().to_string(), - server_name: "linuxiarz.pl".to_string(), - now: Utc::now(), + graphs: &graphs, + last_update: &last_update, + server_name: "linuxiarz.pl", + year: now.year(), }; HttpResponse::Ok().content_type("text/html").body(template.render().unwrap()) } @@ -95,7 +111,6 @@ async fn main() -> std::io::Result<()> { env_logger::init(); let config = Config::load(); - // Tło do aktualizacji RRD let config_clone = config.clone(); tokio::spawn(async move { let mut interval = time::interval(Duration::from_secs(config_clone.rrd_update_interval)); diff --git a/src/rrd.rs b/src/rrd.rs index f6f549b..0a812e5 100644 --- a/src/rrd.rs +++ b/src/rrd.rs @@ -1,12 +1,12 @@ -use crate::config::Config; // Import Config -// Zakładam użycie biblioteki rrd; dostosuj +use crate::config::Config; +use log; pub fn update_rrd_stats(config: &Config) { - // Pobierz dane z TS3 i zaktualizuj RRD (na podstawie app.py[1]) - log::info!("Updating RRD stats"); + // Pobierz online users jak w app.py[1], update RRD + log::info!("Updating RRD stats for file: {}", config.rrd_file); } pub fn generate_graphs(config: &Config) { - // Generuj wykresy (na podstawie create_rrd_graph w app.py[1]) - log::info!("Generating graphs"); + // Generuj wykresy dla hour, day, 72h, week jak w app.py[1] + log::info!("Generating graphs with interval: {}", config.rrd_update_interval); } diff --git a/src/ts3.rs b/src/ts3.rs index 609c861..2c338c2 100644 --- a/src/ts3.rs +++ b/src/ts3.rs @@ -1,20 +1,33 @@ use std::net::TcpStream; -use std::io::{BufRead, BufReader, Write}; -use crate::config::Config; // Import Config +use std::io::Write; +use crate::config::Config; pub fn get_ts3_connection(config: &Config) -> Result { - let mut stream = TcpStream::connect(format!("{}:{}", config.ts3_server, config.ts3_query_port)) + let stream = TcpStream::connect(format!("{}:{}", config.ts3_server, config.ts3_query_port)) .map_err(|e| e.to_string())?; let mut writer = stream.try_clone().unwrap(); writer.write_all(format!("login {} {}\n", config.ts3_query_user, config.ts3_query_pass).as_bytes()).unwrap(); - // Dodaj odczyt odpowiedzi i obsługę błędów + // Dodaj odczyt odpowiedzi i obsługę błędów, jak w app.py[1] Ok(stream) } -pub fn create_channel(stream: &mut TcpStream, name: &str, topic: &str, password: &str) -> Result { - // Implementacja channelcreate, etc. (uproszczona; dostosuj na podstawie app.py[1]) - let command = format!("channelcreate channel_name={} channel_topic={} channel_password={}\n", name, topic, password); - stream.write_all(command.as_bytes()).unwrap(); - // Parsuj odpowiedź (użyj serde_teamspeak_querystring) - unimplemented!(); // Pełna implementacja wymaga testów +// Symulacja get_client_info z app.py[1] (porównanie IP, zwrot UUID itd.) +pub fn get_client_info(_ts3conn: &mut TcpStream, _ip_address: &str) -> Option { + // Pełna implementacja: Wyślij clientlist, clientinfo, porównaj IP + // Tymczasowo: unimplemented!() + unimplemented!(); +} + +pub struct ClientInfo { + pub uid: String, + pub nickname: String, + pub dbid: u32, + pub clid: u32, + pub ip: String, +} + +pub fn create_channel(_stream: &mut TcpStream, _name: &str, _topic: &str, _password: &str, _client_dbid: u32, _client_clid: u32) -> Result { + // Pełna logika z app.py[1]: channelcreate, setclientchannelgroup, clientmove + // Tymczasowo: unimplemented!() + unimplemented!(); } diff --git a/templates/base.html b/templates/base.html index 7186ad2..58bedff 100644 --- a/templates/base.html +++ b/templates/base.html @@ -21,7 +21,7 @@ {% block content %}{% endblock %}
- TS3 Manager © {{ now.year }} | Hosted by linuxiarz.pl + TS3 Manager © {{ year }} | Hosted by linuxiarz.pl