added gettin opnv setup files

This commit is contained in:
2025-12-09 19:23:54 +01:00
parent f95e9e2427
commit c2408d9a56
13 changed files with 478 additions and 53 deletions

View File

@@ -12,21 +12,51 @@ pub struct Config {
pub economic_lookahead_months: u32, // default: 3
/// Maximum number of parallel scraping tasks (default: 10).
/// This limits concurrency to protect system load and prevent website spamming.
#[serde(default = "default_max_parallel")]
pub max_parallel_tasks: usize,
#[serde(default = "default_max_parallel_instances")]
pub max_parallel_instances: usize,
pub max_tasks_per_instance: usize,
/// VPN rotation configuration
/// If set to "true", enables automatic VPN rotation between sessions
#[serde(default)]
pub enable_vpn_rotation: bool,
/// Comma-separated list of VPN servers/country codes to rotate through.
/// Example: "US-Free#1,UK-Free#1,JP-Free#1" or "US,JP,DE"
/// If empty, VPN rotation is disabled.
#[serde(default)]
pub vpn_servers: String,
/// Number of tasks per session before rotating VPN
/// If set to 0, rotates VPN between economic and corporate phases
#[serde(default = "default_tasks_per_session")]
pub tasks_per_vpn_session: usize,
}
fn default_max_parallel() -> usize {
fn default_max_parallel_instances() -> usize {
10
}
fn default_tasks_per_session() -> usize {
0 // 0 = rotate between economic/corporate
}
fn default_protonvpn_extension_id() -> String {
"ghmbeldphafepmbegfdlkpapadhbakde".to_string()
}
impl Default for Config {
fn default() -> Self {
Self {
economic_start_date: "2007-02-13".to_string(),
corporate_start_date: "2010-01-01".to_string(),
economic_lookahead_months: 3,
max_parallel_tasks: default_max_parallel(),
max_parallel_instances: default_max_parallel_instances(),
max_tasks_per_instance: 0,
enable_vpn_rotation: false,
vpn_servers: String::new(),
tasks_per_vpn_session: default_tasks_per_session(),
}
}
}
@@ -59,19 +89,54 @@ impl Config {
.parse()
.context("Failed to parse ECONOMIC_LOOKAHEAD_MONTHS as u32")?;
let max_parallel_tasks: usize = dotenvy::var("MAX_PARALLEL_TASKS")
let max_parallel_instances: usize = dotenvy::var("MAX_PARALLEL_INSTANCES")
.unwrap_or_else(|_| "10".to_string())
.parse()
.context("Failed to parse MAX_PARALLEL_TASKS as usize")?;
.context("Failed to parse MAX_PARALLEL_INSTANCES as usize")?;
let max_tasks_per_instance: usize = dotenvy::var("MAX_TASKS_PER_INSTANCE")
.unwrap_or_else(|_| "0".to_string())
.parse()
.context("Failed to parse MAX_TASKS_PER_INSTANCE as usize")?;
let enable_vpn_rotation = dotenvy::var("ENABLE_VPN_ROTATION")
.unwrap_or_else(|_| "false".to_string())
.parse::<bool>()
.context("Failed to parse ENABLE_VPN_ROTATION as bool")?;
let vpn_servers = dotenvy::var("VPN_SERVERS")
.unwrap_or_else(|_| String::new());
let tasks_per_vpn_session: usize = dotenvy::var("TASKS_PER_VPN_SESSION")
.unwrap_or_else(|_| "0".to_string())
.parse()
.context("Failed to parse TASKS_PER_VPN_SESSION as usize")?;
Ok(Self {
economic_start_date,
corporate_start_date,
economic_lookahead_months,
max_parallel_tasks,
max_parallel_instances,
max_tasks_per_instance,
enable_vpn_rotation,
vpn_servers,
tasks_per_vpn_session,
})
}
/// Get the list of VPN servers configured for rotation
pub fn get_vpn_servers(&self) -> Vec<String> {
if self.vpn_servers.is_empty() {
Vec::new()
} else {
self.vpn_servers
.split(',')
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect()
}
}
pub fn target_end_date(&self) -> String {
let now = chrono::Local::now().naive_local().date();
let future = now + chrono::Duration::days(30 * self.economic_lookahead_months as i64);