blob: 10b1d203f7f7085b2556b17ebff308b9c6ca2f1d [file] [log] [blame] [edit]
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
use crate::Logger;
use serde::{Deserialize, Serialize};
use std::fs;
use std::fs::File;
use std::path::{Path, PathBuf};
use std::time::{SystemTime, UNIX_EPOCH};
const METADATA_FILE_OLD: &str = "selenium-manager.json";
const METADATA_FILE: &str = "se-metadata.json";
#[derive(Serialize, Deserialize)]
pub struct Browser {
pub browser_name: String,
pub major_browser_version: String,
pub browser_version: String,
pub browser_ttl: u64,
}
#[derive(Serialize, Deserialize)]
pub struct Driver {
pub major_browser_version: String,
pub driver_name: String,
pub driver_version: String,
pub driver_ttl: u64,
}
#[derive(Serialize, Deserialize)]
pub struct Metadata {
pub browsers: Vec<Browser>,
pub drivers: Vec<Driver>,
}
fn get_metadata_path(cache_path: PathBuf) -> PathBuf {
let old_metadata = cache_path.join(METADATA_FILE_OLD);
if old_metadata.exists() {
fs::remove_file(old_metadata).unwrap_or_default();
}
cache_path.join(METADATA_FILE)
}
pub fn now_unix_timestamp() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs()
}
fn new_metadata(log: &Logger) -> Metadata {
log.trace("Metadata file does not exist. Creating a new one".to_string());
Metadata {
browsers: Vec::new(),
drivers: Vec::new(),
}
}
pub fn get_metadata(log: &Logger, cache_path: &Option<PathBuf>) -> Metadata {
if let Some(cache) = cache_path {
let metadata_path = get_metadata_path(cache.clone());
log.trace(format!("Reading metadata from {}", metadata_path.display()));
if metadata_path.exists() {
let metadata_file = File::open(&metadata_path).unwrap();
let metadata: Metadata = match serde_json::from_reader(&metadata_file) {
Ok::<Metadata, serde_json::Error>(mut meta) => {
let now = now_unix_timestamp();
meta.browsers.retain(|b| b.browser_ttl > now);
meta.drivers.retain(|d| d.driver_ttl > now);
meta
}
Err(_e) => new_metadata(log), // Empty metadata
};
return metadata;
}
}
new_metadata(log) // Empty metadata
}
pub fn get_browser_version_from_metadata(
browsers_metadata: &[Browser],
browser_name: &str,
major_browser_version: &str,
) -> Option<String> {
let browser: Vec<&Browser> = browsers_metadata
.iter()
.filter(|b| {
b.browser_name.eq(browser_name) && b.major_browser_version.eq(major_browser_version)
})
.collect();
if browser.is_empty() {
None
} else {
Some(browser.get(0).unwrap().browser_version.to_string())
}
}
pub fn get_driver_version_from_metadata(
drivers_metadata: &[Driver],
driver_name: &str,
major_browser_version: &str,
) -> Option<String> {
let driver: Vec<&Driver> = drivers_metadata
.iter()
.filter(|d| {
d.driver_name.eq(driver_name) && d.major_browser_version.eq(major_browser_version)
})
.collect();
if driver.is_empty() {
None
} else {
Some(driver.get(0).unwrap().driver_version.to_string())
}
}
pub fn create_browser_metadata(
browser_name: &str,
major_browser_version: &str,
browser_version: &str,
browser_ttl: u64,
) -> Browser {
Browser {
browser_name: browser_name.to_string(),
major_browser_version: major_browser_version.to_string(),
browser_version: browser_version.to_string(),
browser_ttl: now_unix_timestamp() + browser_ttl,
}
}
pub fn create_driver_metadata(
major_browser_version: &str,
driver_name: &str,
driver_version: &str,
driver_ttl: u64,
) -> Driver {
Driver {
major_browser_version: major_browser_version.to_string(),
driver_name: driver_name.to_string(),
driver_version: driver_version.to_string(),
driver_ttl: now_unix_timestamp() + driver_ttl,
}
}
pub fn write_metadata(metadata: &Metadata, log: &Logger, cache_path: Option<PathBuf>) {
if let Some(cache) = cache_path {
let metadata_path = get_metadata_path(cache.clone());
log.trace(format!("Writing metadata to {}", metadata_path.display()));
fs::write(
metadata_path,
serde_json::to_string_pretty(metadata).unwrap(),
)
.unwrap_or_else(|err| {
log.warn(format!(
"Metadata cannot be written in cache ({}): {}",
cache.display(),
err
));
});
}
}
pub fn clear_metadata(log: &Logger, path: &str) {
let cache_path = Path::new(path).to_path_buf();
let metadata_path = get_metadata_path(cache_path);
log.debug(format!(
"Deleting metadata file {}",
metadata_path.display()
));
fs::remove_file(metadata_path).unwrap_or_else(|err| {
log.warn(format!("Error deleting metadata file: {}", err));
});
}