diff --git a/README.md b/README.md index 7f4b2dc..8c14155 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Options: $ biliup help Upload video to bilibili. -Usage: biliup [OPTIONS] +Usage: biliup.exe [OPTIONS] Commands: login 登录B站并保存登录信息 @@ -93,6 +93,7 @@ Commands: dump-flv 输出flv元数据 download 下载视频 list 列出所有已上传的视频 + bind 绑定用户与代理(用户通过user_cookie参数指定) help Print this message or the help of the given subcommand(s) Options: @@ -119,7 +120,20 @@ $biliup renew # ./cookies.json ```powershell .\biliup.exe -p http://username:password@proxy.example.com:8080 upload ``` - +您也可以通过以下方式为用户绑定代理 +```powershell +.\biliup.exe -p http://username:password@proxy.example.com:8080 -u myname.json login +``` +通过这样登录的账号会**自动**生成myname-proxy.json文件记录您使用的代理,后续您可以直接使用其他功能 +```powershell +.\biliup.exe -u myname.json upoload +``` +如果代理文件发生变更您可以直接编辑myname-proxy.json文件 +如果您的账号已经登录也可以使用以下命令自动创建代理配置文件 +```powershell +.\biliup.exe -p http://username:password@proxy.example.com:8080 -u myname2.json bind +``` +或者您可以手动建立yourname-proxy.json文件并填入"代理地址" ### Windows 演示 登录: diff --git a/crates/biliup-cli/src/cli.rs b/crates/biliup-cli/src/cli.rs index 1993712..fc9c415 100644 --- a/crates/biliup-cli/src/cli.rs +++ b/crates/biliup-cli/src/cli.rs @@ -134,6 +134,8 @@ pub enum Commands { #[arg(long)] not_pubed: bool, }, + /// 绑定用户与代理(用户通过user_cookie参数指定) + Bind, } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] diff --git a/crates/biliup-cli/src/main.rs b/crates/biliup-cli/src/main.rs index a5fc28d..d5e0b79 100644 --- a/crates/biliup-cli/src/main.rs +++ b/crates/biliup-cli/src/main.rs @@ -6,6 +6,7 @@ mod uploader; use anyhow::Result; use time::macros::format_description; +use tracing::info; use crate::cli::{Cli, Commands}; use crate::downloader::{download, generate_json}; @@ -16,6 +17,22 @@ use clap::Parser; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; +// 判断代理是否有效 +async fn check_proxy(proxy: &str) -> Result<()> { + let client = reqwest::Client::builder() + .proxy(reqwest::Proxy::all(proxy)?) + .build()?; + let resp = client.get("https://www.bilibili.com/").send().await?; + if resp.status().is_success() { + Ok(()) + } else { + Err(anyhow::anyhow!("代理无效")) + } +} + + + + #[tokio::main] async fn main() -> Result<()> { // a builder for `FmtSubscriber`. @@ -27,7 +44,7 @@ async fn main() -> Result<()> { // .finish(); // tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed"); - let cli = Cli::parse(); + let mut cli = Cli::parse(); //下面需要修改cli unsafe { time::util::local_offset::set_soundness(time::util::local_offset::Soundness::Unsound); @@ -36,7 +53,39 @@ async fn main() -> Result<()> { let timer = tracing_subscriber::fmt::time::LocalTime::new(format_description!( "[year]-[month]-[day] [hour]:[minute]:[second]" )); - + + let proxy = cli.proxy.as_deref(); + // 判断proxy是否为空 如果为空则尝试从user_cookie的文件名-proxy.json中读取 + if proxy.is_none() { + let file_name = cli.user_cookie.file_name().unwrap().to_str().unwrap(); + // 去除文件名后缀 + let file_name = file_name.split('.').collect::>()[0]; + let proxy_file = format!("{}-proxy.json", file_name); + let proxy_file = std::path::Path::new(&proxy_file); + if proxy_file.exists() { + // 如果文件存在则读取文件 + let proxy_str = std::fs::read_to_string(proxy_file)?; + let proxy_str = proxy_str.trim(); + // 去除双引号 + let proxy_str = proxy_str.trim_matches(|c| c == '\"'); + // 去除中文引号 + let proxy_str = proxy_str.trim_matches(|c| c == '“' || c == '”'); + if !proxy_str.is_empty() { + info!("读取到代理配置: {}", proxy_str); + // 检查代理是否有效 + let is_available = check_proxy(proxy_str).await; + if is_available.is_err() { + return Err(anyhow::anyhow!("代理无效")); + } + cli.proxy = Some(proxy_str.to_string()); + } + } + }else { + // 检查代理是否有效 + check_proxy(proxy.unwrap()).await?; + } + // 重新使cli不可变 + let cli = cli; tracing_subscriber::registry() .with(tracing_subscriber::EnvFilter::new(&cli.rust_log)) .with(tracing_subscriber::fmt::layer().with_timer(timer)) @@ -111,6 +160,25 @@ async fn main() -> Result<()> { cli.proxy.as_deref(), ) .await? + }, + Commands::Bind => { + // 判断proxy是否为空 + if cli.proxy.is_none() { + return Err(anyhow::anyhow!("请指定代理")); + } + // 判断user_cookie是否存在 + if cli.user_cookie.exists() { + return Err(anyhow::anyhow!("指定的user_cookie文件不存在")); + } + let proxy = cli.proxy.as_deref().unwrap(); + // 判断代理是否有效 + let is_available = check_proxy(proxy).await; + if is_available.is_err() { + return Err(anyhow::anyhow!("代理无效")); + } + let user = cli.user_cookie.file_name().unwrap().to_str().unwrap().split('.').collect::>()[0]; + let file_name = format!("{}-proxy.json", user); + std::fs::write(file_name, proxy)?; } }; Ok(()) diff --git a/crates/biliup-cli/src/uploader.rs b/crates/biliup-cli/src/uploader.rs index 3715c56..e03b72c 100644 --- a/crates/biliup-cli/src/uploader.rs +++ b/crates/biliup-cli/src/uploader.rs @@ -46,9 +46,19 @@ pub async fn login(user_cookie: PathBuf, proxy: Option<&str>) -> Result<()> { 5 => login_by_webqr_cookies(client).await?, _ => panic!(), }; - let file = std::fs::File::create(user_cookie)?; + let file = std::fs::File::create(user_cookie.clone())?; serde_json::to_writer_pretty(&file, &info)?; info!("登录成功,数据保存在{:?}", file); + // 判断proxy是否为空 + if let Some(proxy) = proxy { + let user_cookie = user_cookie.clone(); + let file_name = user_cookie.file_name().unwrap().to_str().unwrap(); + let file_name = file_name.split('.').collect::>()[0]; + let file_name = format!("{}-proxy.json", file_name); + let file = std::fs::File::create(file_name)?; + serde_json::to_writer_pretty(&file, proxy)?; + info!("代理数据保存在{:?}", file); + } Ok(()) }