191 lines
4.6 KiB
Rust
191 lines
4.6 KiB
Rust
// Browser session management
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use std::collections::HashMap;
|
|
use std::sync::Arc;
|
|
use tokio::sync::RwLock;
|
|
use chrono::{DateTime, Utc};
|
|
|
|
/// Browser session configuration
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct SessionConfig {
|
|
/// WebDriver URL (e.g., "http://localhost:4444")
|
|
pub webdriver_url: String,
|
|
|
|
/// Browser type (chrome, firefox, etc.)
|
|
pub browser_type: BrowserType,
|
|
|
|
/// Headless mode
|
|
pub headless: bool,
|
|
|
|
/// Window size (width, height)
|
|
pub window_size: Option<(u32, u32)>,
|
|
|
|
/// Page load timeout in seconds
|
|
pub page_load_timeout: u64,
|
|
|
|
/// Script timeout in seconds
|
|
pub script_timeout: u64,
|
|
|
|
/// Implicit wait timeout in milliseconds
|
|
pub implicit_wait_timeout: u64,
|
|
|
|
/// Custom browser arguments
|
|
pub browser_args: Vec<String>,
|
|
}
|
|
|
|
impl Default for SessionConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
webdriver_url: "http://localhost:4444".to_string(),
|
|
browser_type: BrowserType::Chrome,
|
|
headless: true,
|
|
window_size: Some((1920, 1080)),
|
|
page_load_timeout: 30,
|
|
script_timeout: 30,
|
|
implicit_wait_timeout: 1000,
|
|
browser_args: vec![],
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
#[serde(rename_all = "lowercase")]
|
|
pub enum BrowserType {
|
|
Chrome,
|
|
Firefox,
|
|
Edge,
|
|
Safari,
|
|
}
|
|
|
|
/// Active browser session
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct BrowserSession {
|
|
/// Unique session identifier
|
|
pub id: String,
|
|
|
|
/// Session name for display
|
|
pub name: String,
|
|
|
|
/// Current URL
|
|
pub current_url: Option<String>,
|
|
|
|
/// Page title
|
|
pub title: Option<String>,
|
|
|
|
/// Session status
|
|
pub status: SessionStatus,
|
|
|
|
/// Creation timestamp
|
|
pub created_at: DateTime<Utc>,
|
|
|
|
/// Last activity timestamp
|
|
pub last_activity: DateTime<Utc>,
|
|
|
|
/// Session configuration
|
|
pub config: SessionConfig,
|
|
|
|
/// Custom metadata
|
|
pub metadata: HashMap<String, String>,
|
|
}
|
|
|
|
impl BrowserSession {
|
|
pub fn new(id: String, config: SessionConfig) -> Self {
|
|
let now = Utc::now();
|
|
Self {
|
|
id,
|
|
name: format!("Browser Session"),
|
|
current_url: None,
|
|
title: None,
|
|
status: SessionStatus::Connected,
|
|
created_at: now,
|
|
last_activity: now,
|
|
config,
|
|
metadata: HashMap::new(),
|
|
}
|
|
}
|
|
|
|
pub fn touch(&mut self) {
|
|
self.last_activity = Utc::now();
|
|
}
|
|
|
|
pub fn update_location(&mut self, url: Option<String>, title: Option<String>) {
|
|
self.current_url = url;
|
|
self.title = title;
|
|
self.touch();
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
#[serde(rename_all = "lowercase")]
|
|
pub enum SessionStatus {
|
|
Connecting,
|
|
Connected,
|
|
Active,
|
|
Idle,
|
|
Disconnected,
|
|
Error,
|
|
}
|
|
|
|
/// Session manager for multiple browser instances
|
|
pub struct SessionManager {
|
|
sessions: Arc<RwLock<HashMap<String, BrowserSession>>>,
|
|
}
|
|
|
|
impl SessionManager {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
sessions: Arc::new(RwLock::new(HashMap::new())),
|
|
}
|
|
}
|
|
|
|
pub async fn add_session(&self, session: BrowserSession) {
|
|
let mut sessions = self.sessions.write().await;
|
|
sessions.insert(session.id.clone(), session);
|
|
}
|
|
|
|
pub async fn get_session(&self, id: &str) -> Option<BrowserSession> {
|
|
let sessions = self.sessions.read().await;
|
|
sessions.get(id).cloned()
|
|
}
|
|
|
|
pub async fn update_session(&self, id: &str, updater: impl FnOnce(&mut BrowserSession)) {
|
|
let mut sessions = self.sessions.write().await;
|
|
if let Some(session) = sessions.get_mut(id) {
|
|
updater(session);
|
|
}
|
|
}
|
|
|
|
pub async fn remove_session(&self, id: &str) -> Option<BrowserSession> {
|
|
let mut sessions = self.sessions.write().await;
|
|
sessions.remove(id)
|
|
}
|
|
|
|
pub async fn list_sessions(&self) -> Vec<BrowserSession> {
|
|
let sessions = self.sessions.read().await;
|
|
sessions.values().cloned().collect()
|
|
}
|
|
|
|
/// Get the number of active sessions
|
|
/// Reserved for future status dashboard
|
|
#[allow(dead_code)]
|
|
pub async fn session_count(&self) -> usize {
|
|
let sessions = self.sessions.read().await;
|
|
sessions.len()
|
|
}
|
|
}
|
|
|
|
impl Default for SessionManager {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl Clone for SessionManager {
|
|
fn clone(&self) -> Self {
|
|
Self {
|
|
sessions: Arc::clone(&self.sessions),
|
|
}
|
|
}
|
|
}
|