feat: add storage_dir option
feat(cli): store config in userdata folder
This commit is contained in:
parent
f036106a73
commit
c688ff74e9
5 changed files with 47 additions and 33 deletions
|
|
@ -7,31 +7,11 @@ edition = "2021"
|
||||||
default = ["rustls-tls-native-roots"]
|
default = ["rustls-tls-native-roots"]
|
||||||
|
|
||||||
# Reqwest TLS options
|
# Reqwest TLS options
|
||||||
native-tls = [
|
native-tls = ["reqwest/native-tls", "rustypipe/native-tls", "rustypipe-downloader/native-tls"]
|
||||||
"reqwest/native-tls",
|
native-tls-alpn = ["reqwest/native-tls-alpn", "rustypipe/native-tls-alpn", "rustypipe-downloader/native-tls-alpn"]
|
||||||
"rustypipe/native-tls",
|
native-tls-vendored = ["reqwest/native-tls-vendored", "rustypipe/native-tls-vendored", "rustypipe-downloader/native-tls-vendored"]
|
||||||
"rustypipe-downloader/native-tls",
|
rustls-tls-webpki-roots = ["reqwest/rustls-tls-webpki-roots", "rustypipe/rustls-tls-webpki-roots", "rustypipe-downloader/rustls-tls-webpki-roots"]
|
||||||
]
|
rustls-tls-native-roots = ["reqwest/rustls-tls-native-roots", "rustypipe/rustls-tls-native-roots", "rustypipe-downloader/rustls-tls-native-roots"]
|
||||||
native-tls-alpn = [
|
|
||||||
"reqwest/native-tls-alpn",
|
|
||||||
"rustypipe/native-tls-alpn",
|
|
||||||
"rustypipe-downloader/native-tls-alpn",
|
|
||||||
]
|
|
||||||
native-tls-vendored = [
|
|
||||||
"reqwest/native-tls-vendored",
|
|
||||||
"rustypipe/native-tls-vendored",
|
|
||||||
"rustypipe-downloader/native-tls-vendored",
|
|
||||||
]
|
|
||||||
rustls-tls-webpki-roots = [
|
|
||||||
"reqwest/rustls-tls-webpki-roots",
|
|
||||||
"rustypipe/rustls-tls-webpki-roots",
|
|
||||||
"rustypipe-downloader/rustls-tls-webpki-roots",
|
|
||||||
]
|
|
||||||
rustls-tls-native-roots = [
|
|
||||||
"reqwest/rustls-tls-native-roots",
|
|
||||||
"rustypipe/rustls-tls-native-roots",
|
|
||||||
"rustypipe-downloader/rustls-tls-native-roots",
|
|
||||||
]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rustypipe = { path = "../", default-features = false }
|
rustypipe = { path = "../", default-features = false }
|
||||||
|
|
@ -46,3 +26,4 @@ env_logger = "0.10.0"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_json = "1.0.82"
|
serde_json = "1.0.82"
|
||||||
serde_yaml = "0.9.19"
|
serde_yaml = "0.9.19"
|
||||||
|
dirs = "5.0.0"
|
||||||
|
|
|
||||||
|
|
@ -384,7 +384,11 @@ async fn main() {
|
||||||
|
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
let rp = RustyPipe::new();
|
let mut storage_dir = dirs::data_dir().expect("no data dir");
|
||||||
|
storage_dir.push("rustypipe");
|
||||||
|
_ = std::fs::create_dir(&storage_dir);
|
||||||
|
|
||||||
|
let rp = RustyPipe::builder().storage_dir(storage_dir).build();
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
Commands::Download {
|
Commands::Download {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ use std::{
|
||||||
|
|
||||||
use log::error;
|
use log::error;
|
||||||
|
|
||||||
|
pub(crate) const DEFAULT_CACHE_FILE: &str = "rustypipe_cache.json";
|
||||||
|
|
||||||
/// RustyPipe has to cache some information fetched from YouTube: specifically
|
/// RustyPipe has to cache some information fetched from YouTube: specifically
|
||||||
/// the client versions and the JavaScript code used to deobfuscate the stream URLs.
|
/// the client versions and the JavaScript code used to deobfuscate the stream URLs.
|
||||||
///
|
///
|
||||||
|
|
@ -42,7 +44,7 @@ impl FileStorage {
|
||||||
impl Default for FileStorage {
|
impl Default for FileStorage {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
path: Path::new("rustypipe_cache.json").into(),
|
path: Path::new(DEFAULT_CACHE_FILE).into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ mod video_details;
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "rss")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "rss")))]
|
||||||
mod channel_rss;
|
mod channel_rss;
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{borrow::Cow, fmt::Debug, time::Duration};
|
use std::{borrow::Cow, fmt::Debug, time::Duration};
|
||||||
|
|
||||||
|
|
@ -34,11 +35,11 @@ use time::OffsetDateTime;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cache::{CacheStorage, FileStorage},
|
cache::{CacheStorage, FileStorage, DEFAULT_CACHE_FILE},
|
||||||
deobfuscate::DeobfData,
|
deobfuscate::DeobfData,
|
||||||
error::{Error, ExtractionError},
|
error::{Error, ExtractionError},
|
||||||
param::{Country, Language},
|
param::{Country, Language},
|
||||||
report::{FileReporter, Level, Report, Reporter},
|
report::{FileReporter, Level, Report, Reporter, DEFAULT_REPORT_DIR},
|
||||||
serializer::MapResult,
|
serializer::MapResult,
|
||||||
util,
|
util,
|
||||||
};
|
};
|
||||||
|
|
@ -247,6 +248,7 @@ pub struct RustyPipeBuilder {
|
||||||
timeout: DefaultOpt<Duration>,
|
timeout: DefaultOpt<Duration>,
|
||||||
user_agent: Option<String>,
|
user_agent: Option<String>,
|
||||||
default_opts: RustyPipeOpts,
|
default_opts: RustyPipeOpts,
|
||||||
|
storage_dir: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DefaultOpt<T> {
|
enum DefaultOpt<T> {
|
||||||
|
|
@ -361,6 +363,7 @@ impl RustyPipeBuilder {
|
||||||
timeout: DefaultOpt::Default,
|
timeout: DefaultOpt::Default,
|
||||||
n_http_retries: 2,
|
n_http_retries: 2,
|
||||||
user_agent: None,
|
user_agent: None,
|
||||||
|
storage_dir: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -378,7 +381,15 @@ impl RustyPipeBuilder {
|
||||||
|
|
||||||
let http = client_builder.build().unwrap();
|
let http = client_builder.build().unwrap();
|
||||||
|
|
||||||
let cdata = if let DefaultOpt::Some(storage) = &self.storage {
|
let storage_dir = self.storage_dir.unwrap_or_default();
|
||||||
|
|
||||||
|
let storage = self.storage.or_default(|| {
|
||||||
|
let mut cache_file = storage_dir.clone();
|
||||||
|
cache_file.push(DEFAULT_CACHE_FILE);
|
||||||
|
Box::new(FileStorage::new(cache_file))
|
||||||
|
});
|
||||||
|
|
||||||
|
let cdata = if let Some(storage) = &storage {
|
||||||
if let Some(data) = storage.read() {
|
if let Some(data) = storage.read() {
|
||||||
match serde_json::from_str::<CacheData>(&data) {
|
match serde_json::from_str::<CacheData>(&data) {
|
||||||
Ok(data) => data,
|
Ok(data) => data,
|
||||||
|
|
@ -397,8 +408,12 @@ impl RustyPipeBuilder {
|
||||||
RustyPipe {
|
RustyPipe {
|
||||||
inner: Arc::new(RustyPipeRef {
|
inner: Arc::new(RustyPipeRef {
|
||||||
http,
|
http,
|
||||||
storage: self.storage.or_default(|| Box::<FileStorage>::default()),
|
storage,
|
||||||
reporter: self.reporter.or_default(|| Box::<FileReporter>::default()),
|
reporter: self.reporter.or_default(|| {
|
||||||
|
let mut report_dir = storage_dir;
|
||||||
|
report_dir.push(DEFAULT_REPORT_DIR);
|
||||||
|
Box::new(FileReporter::new(report_dir))
|
||||||
|
}),
|
||||||
n_http_retries: self.n_http_retries,
|
n_http_retries: self.n_http_retries,
|
||||||
consent_cookie: format!(
|
consent_cookie: format!(
|
||||||
"{}={}{}",
|
"{}={}{}",
|
||||||
|
|
@ -416,6 +431,16 @@ impl RustyPipeBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the default directory to store the cachefile and reports.
|
||||||
|
///
|
||||||
|
/// This option has no effect if the storage backend or reporter are manually set or disabled.
|
||||||
|
///
|
||||||
|
/// **Default value**: current working directory
|
||||||
|
pub fn storage_dir<P: Into<PathBuf>>(mut self, path: P) -> Self {
|
||||||
|
self.storage_dir = Some(path.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a [`CacheStorage`] backend for persisting cached information
|
/// Add a [`CacheStorage`] backend for persisting cached information
|
||||||
/// (YouTube client versions, deobfuscation code) between
|
/// (YouTube client versions, deobfuscation code) between
|
||||||
/// program executions.
|
/// program executions.
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ use time::{macros::format_description, OffsetDateTime};
|
||||||
|
|
||||||
use crate::{deobfuscate::DeobfData, util};
|
use crate::{deobfuscate::DeobfData, util};
|
||||||
|
|
||||||
|
pub(crate) const DEFAULT_REPORT_DIR: &str = "rustypipe_reports";
|
||||||
|
|
||||||
const FILENAME_FORMAT: &[time::format_description::FormatItem] =
|
const FILENAME_FORMAT: &[time::format_description::FormatItem] =
|
||||||
format_description!("[year]-[month]-[day]_[hour]-[minute]-[second]");
|
format_description!("[year]-[month]-[day]_[hour]-[minute]-[second]");
|
||||||
|
|
||||||
|
|
@ -137,7 +139,7 @@ impl FileReporter {
|
||||||
impl Default for FileReporter {
|
impl Default for FileReporter {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
path: Path::new("rustypipe_reports").to_path_buf(),
|
path: Path::new(DEFAULT_REPORT_DIR).to_path_buf(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Reference in a new issue