Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/rust/src/metadata.rs
2885 views
1
// Licensed to the Software Freedom Conservancy (SFC) under one
2
// or more contributor license agreements. See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership. The SFC licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License. You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied. See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
use crate::stats::Props;
19
use crate::Logger;
20
use serde::{Deserialize, Serialize};
21
use std::fs;
22
use std::fs::File;
23
use std::path::{Path, PathBuf};
24
use std::time::{SystemTime, UNIX_EPOCH};
25
26
const METADATA_FILE: &str = "se-metadata.json";
27
28
#[derive(Serialize, Deserialize)]
29
pub struct Stats {
30
pub browser: String,
31
pub browser_version: String,
32
pub os: String,
33
pub arch: String,
34
pub lang: String,
35
pub selenium_version: String,
36
pub stats_ttl: u64,
37
}
38
39
#[derive(Serialize, Deserialize)]
40
pub struct Browser {
41
pub browser_name: String,
42
pub major_browser_version: String,
43
pub browser_version: String,
44
pub browser_ttl: u64,
45
}
46
47
#[derive(Serialize, Deserialize)]
48
pub struct Driver {
49
pub major_browser_version: String,
50
pub driver_name: String,
51
pub driver_version: String,
52
pub driver_ttl: u64,
53
}
54
55
#[derive(Serialize, Deserialize)]
56
pub struct Metadata {
57
pub browsers: Vec<Browser>,
58
pub drivers: Vec<Driver>,
59
pub stats: Vec<Stats>,
60
}
61
62
fn get_metadata_path(cache_path: PathBuf) -> PathBuf {
63
cache_path.join(METADATA_FILE)
64
}
65
66
pub fn now_unix_timestamp() -> u64 {
67
SystemTime::now()
68
.duration_since(UNIX_EPOCH)
69
.unwrap()
70
.as_secs()
71
}
72
73
fn new_metadata(log: &Logger) -> Metadata {
74
log.trace("Metadata file does not exist. Creating a new one".to_string());
75
Metadata {
76
browsers: Vec::new(),
77
drivers: Vec::new(),
78
stats: Vec::new(),
79
}
80
}
81
82
pub fn get_metadata(log: &Logger, cache_path: &Option<PathBuf>) -> Metadata {
83
if let Some(cache) = cache_path {
84
let metadata_path = get_metadata_path(cache.clone());
85
log.trace(format!("Reading metadata from {}", metadata_path.display()));
86
87
if metadata_path.exists() {
88
let metadata_file = File::open(&metadata_path).unwrap();
89
let metadata: Metadata = match serde_json::from_reader(&metadata_file) {
90
Ok::<Metadata, serde_json::Error>(mut meta) => {
91
let now = now_unix_timestamp();
92
meta.browsers.retain(|b| b.browser_ttl > now);
93
meta.drivers.retain(|d| d.driver_ttl > now);
94
meta.stats.retain(|s| s.stats_ttl > now);
95
meta
96
}
97
Err(_e) => new_metadata(log), // Empty metadata
98
};
99
return metadata;
100
}
101
}
102
new_metadata(log) // Empty metadata
103
}
104
105
pub fn get_browser_version_from_metadata(
106
browsers_metadata: &[Browser],
107
browser_name: &str,
108
major_browser_version: &str,
109
) -> Option<String> {
110
let browser: Vec<&Browser> = browsers_metadata
111
.iter()
112
.filter(|b| {
113
b.browser_name.eq(browser_name) && b.major_browser_version.eq(major_browser_version)
114
})
115
.collect();
116
if browser.is_empty() {
117
None
118
} else {
119
Some(browser.first().unwrap().browser_version.to_string())
120
}
121
}
122
123
pub fn get_driver_version_from_metadata(
124
drivers_metadata: &[Driver],
125
driver_name: &str,
126
major_browser_version: &str,
127
) -> Option<String> {
128
let driver: Vec<&Driver> = drivers_metadata
129
.iter()
130
.filter(|d| {
131
d.driver_name.eq(driver_name) && d.major_browser_version.eq(major_browser_version)
132
})
133
.collect();
134
if driver.is_empty() {
135
None
136
} else {
137
Some(driver.first().unwrap().driver_version.to_string())
138
}
139
}
140
141
pub fn is_stats_in_metadata(stats_metadata: &[Stats], props: &Props) -> bool {
142
let props: Vec<&Stats> = stats_metadata
143
.iter()
144
.filter(|p| {
145
p.browser.eq(&props.browser)
146
&& p.browser_version.eq(&props.browser_version)
147
&& p.os.eq(&props.os)
148
&& p.arch.eq(&props.arch)
149
&& p.lang.eq(&props.lang)
150
&& p.selenium_version.eq(&props.selenium_version)
151
})
152
.collect();
153
!props.is_empty()
154
}
155
156
pub fn create_browser_metadata(
157
browser_name: &str,
158
major_browser_version: &str,
159
browser_version: &str,
160
browser_ttl: u64,
161
) -> Browser {
162
Browser {
163
browser_name: browser_name.to_string(),
164
major_browser_version: major_browser_version.to_string(),
165
browser_version: browser_version.to_string(),
166
browser_ttl: now_unix_timestamp() + browser_ttl,
167
}
168
}
169
170
pub fn create_driver_metadata(
171
major_browser_version: &str,
172
driver_name: &str,
173
driver_version: &str,
174
driver_ttl: u64,
175
) -> Driver {
176
Driver {
177
major_browser_version: major_browser_version.to_string(),
178
driver_name: driver_name.to_string(),
179
driver_version: driver_version.to_string(),
180
driver_ttl: now_unix_timestamp() + driver_ttl,
181
}
182
}
183
184
pub fn create_stats_metadata(props: &Props, stats_ttl: u64) -> Stats {
185
Stats {
186
browser: props.browser.to_string(),
187
browser_version: props.browser_version.to_string(),
188
os: props.os.to_string(),
189
arch: props.arch.to_string(),
190
lang: props.lang.to_string(),
191
selenium_version: props.selenium_version.to_string(),
192
stats_ttl: now_unix_timestamp() + stats_ttl,
193
}
194
}
195
196
pub fn write_metadata(metadata: &Metadata, log: &Logger, cache_path: Option<PathBuf>) {
197
if let Some(cache) = cache_path {
198
let metadata_path = get_metadata_path(cache.clone());
199
log.trace(format!("Writing metadata to {}", metadata_path.display()));
200
fs::write(
201
metadata_path,
202
serde_json::to_string_pretty(metadata).unwrap(),
203
)
204
.unwrap_or_else(|err| {
205
log.warn(format!(
206
"Metadata cannot be written in cache ({}): {}",
207
cache.display(),
208
err
209
));
210
});
211
}
212
}
213
214
pub fn clear_metadata(log: &Logger, path: &str) {
215
let cache_path = Path::new(path).to_path_buf();
216
let metadata_path = get_metadata_path(cache_path);
217
log.debug(format!(
218
"Deleting metadata file {}",
219
metadata_path.display()
220
));
221
fs::remove_file(metadata_path).unwrap_or_else(|err| {
222
log.warn(format!("Error deleting metadata file: {}", err));
223
});
224
}
225
226