diff --git a/Cargo.lock b/Cargo.lock index 22b92a0..b9520b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -395,7 +395,7 @@ dependencies = [ [[package]] name = "biliup-cli" -version = "1.1.17" +version = "1.1.18" dependencies = [ "async-channel", "async-trait", @@ -2552,9 +2552,9 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.26.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383" +checksum = "37a6df7eab65fc7bee654a421404947e10a0f7085b6951bf2ea395f4659fb0cf" dependencies = [ "anyhow", "indoc", @@ -2570,18 +2570,18 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.26.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f" +checksum = "f77d387774f6f6eec64a004eac0ed525aab7fa1966d94b42f743797b3e395afb" dependencies = [ "target-lexicon 0.13.2", ] [[package]] name = "pyo3-ffi" -version = "0.26.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105" +checksum = "2dd13844a4242793e02df3e2ec093f540d948299a6a77ea9ce7afd8623f542be" dependencies = [ "libc", "pyo3-build-config", @@ -2589,9 +2589,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.26.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded" +checksum = "eaf8f9f1108270b90d3676b8679586385430e5c0bb78bb5f043f95499c821a71" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -2601,9 +2601,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.26.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf" +checksum = "70a3b2274450ba5288bc9b8c1b69ff569d1d61189d4bff38f8d22e03d17f932b" dependencies = [ "heck", "proc-macro2", @@ -2615,8 +2615,7 @@ dependencies = [ [[package]] name = "pythonize" version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11e06e4cff9be2bbf2bddf28a486ae619172ea57e79787f856572878c62dcfe2" +source = "git+https://github.com/davidhewitt/pythonize.git?rev=6140fe00f601f418371d969bedbcd27944a6956a#6140fe00f601f418371d969bedbcd27944a6956a" dependencies = [ "pyo3", "serde", @@ -3642,7 +3641,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stream-gears" -version = "1.1.17" +version = "1.1.18" dependencies = [ "async-channel", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index f4cbef7..e1af869 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ members = [ resolver = "3" [workspace.package] -version = "1.1.17" +version = "1.1.18" [workspace.dependencies] serde = { version = "1.0", features = ["derive"] } diff --git a/biliup/__main__.py b/biliup/__main__.py index dac2c53..4c4c31e 100644 --- a/biliup/__main__.py +++ b/biliup/__main__.py @@ -15,48 +15,13 @@ from biliup.common.log import DebugLevelFilter def arg_parser(): - daemon = Daemon('watch_process.pid', lambda: main(args)) - parser = argparse.ArgumentParser(description='Stream download and upload, not only for bilibili.') - parser.add_argument('--version', action='version', version=f"v{__version__}") - parser.add_argument('-H', help='web api host [default: 0.0.0.0]', dest='host') - if IS_FROZEN: - parser.add_argument( - '-P', - help='web api port (REQUIRED)', - dest='port', - required=True, - type=int - ) - else: - parser.add_argument('-P', help='web api port [default: 19159]', default=19159, dest='port') - parser.add_argument('--no-http', action='store_true', help='disable web api') - parser.add_argument('--static-dir', help='web static files directory for custom ui') - parser.add_argument('--password', help='web ui password ,default username is biliup', dest='password') - parser.add_argument('-v', '--verbose', action="store_const", const=logging.DEBUG, help="Increase output verbosity") - parser.add_argument('--config', type=argparse.FileType(mode='rb'), - help='Location of the configuration file (default "./config.yaml")') - parser.add_argument('--no-access-log', action='store_true', help='disable web access log') - subparsers = parser.add_subparsers(help='Windows does not support this sub-command.') - # create the parser for the "start" command - parser_start = subparsers.add_parser('start', help='Run as a daemon process.') - parser_start.set_defaults(func=daemon.start) - parser_stop = subparsers.add_parser('stop', help='Stop daemon according to "watch_process.pid".') - parser_stop.set_defaults(func=daemon.stop) - parser_restart = subparsers.add_parser('restart') - parser_restart.set_defaults(func=daemon.restart) - parser.set_defaults(func=lambda: asyncio.run(main(args))) - args = parser.parse_args() - - if args.verbose: - LOG_CONF['loggers']['biliup']['level'] = args.verbose - LOG_CONF['root']['level'] = args.verbose logging.config.dictConfig(LOG_CONF) logging.getLogger('httpx').addFilter(DebugLevelFilter()) - args.func() + asyncio.run(main()) -async def main(args): +async def main(): # from biliup.app import event_manager # event_manager.start() diff --git a/crates/biliup-cli/src/cli.rs b/crates/biliup-cli/src/cli.rs index ab6582d..60a33de 100644 --- a/crates/biliup-cli/src/cli.rs +++ b/crates/biliup-cli/src/cli.rs @@ -2,7 +2,7 @@ use biliup::uploader::bilibili::{Studio, Vid}; use biliup::uploader::util::SubmitOption; use clap::{Parser, Subcommand}; -use biliup_cli::UploadLine; +use crate::UploadLine; use std::path::PathBuf; #[derive(Parser)] @@ -123,7 +123,11 @@ pub enum Commands { /// Port to use #[arg(short, long, default_value = "19159")] - port: u16, + port: u16, + + /// Port to use + #[arg(short, long, default_value = "false")] + auth: bool, }, /// 列出所有已上传的视频 List { diff --git a/crates/biliup-cli/src/downloader.rs b/crates/biliup-cli/src/downloader.rs index 7172848..5184522 100644 --- a/crates/biliup-cli/src/downloader.rs +++ b/crates/biliup-cli/src/downloader.rs @@ -7,7 +7,7 @@ use biliup::downloader::flv_writer; use biliup::downloader::flv_writer::{FlvTag, TagDataHeader}; use biliup::downloader::httpflv::map_parse_err; use biliup::downloader::util::Segmentable; -use biliup_cli::server::errors::{AppError, AppResult}; +use crate::server::errors::{AppError, AppResult}; use bytes::{Buf, BufMut, Bytes, BytesMut}; use error_stack::ResultExt; use std::io::{BufReader, BufWriter, ErrorKind, Read}; diff --git a/crates/biliup-cli/src/lib.rs b/crates/biliup-cli/src/lib.rs index f4e7c42..ee40184 100644 --- a/crates/biliup-cli/src/lib.rs +++ b/crates/biliup-cli/src/lib.rs @@ -1,4 +1,7 @@ pub mod server; +pub mod cli; +pub mod downloader; +pub mod uploader; // use crate::server::api::router::ApplicationController; use crate::server::app::ApplicationController; @@ -12,7 +15,7 @@ use error_stack::ResultExt; use std::net::ToSocketAddrs; use std::sync::{Arc, RwLock}; -pub async fn run(addr: (&str, u16)) -> AppResult<()> { +pub async fn run(addr: (&str, u16), auth: bool) -> AppResult<()> { // let config = Arc::new(AppConfig::parse()); tracing::info!( @@ -37,7 +40,7 @@ pub async fn run(addr: (&str, u16)) -> AppResult<()> { .change_context(AppError::Unknown)? .next() .unwrap(); - ApplicationController::serve(&addr, service_register) + ApplicationController::serve(&addr, auth, service_register) .await .attach("could not initialize application routes")?; Ok(()) diff --git a/crates/biliup-cli/src/main.rs b/crates/biliup-cli/src/main.rs index f4e0c9b..c02d516 100644 --- a/crates/biliup-cli/src/main.rs +++ b/crates/biliup-cli/src/main.rs @@ -1,12 +1,8 @@ -mod cli; -mod downloader; -mod uploader; - use time::macros::format_description; -use crate::cli::{Cli, Commands}; -use crate::downloader::{download, generate_json}; -use crate::uploader::{append, list, login, renew, show, upload_by_command, upload_by_config}; +use biliup_cli::cli::{Cli, Commands}; +use biliup_cli::downloader::{download, generate_json}; +use biliup_cli::uploader::{append, list, login, renew, show, upload_by_command, upload_by_config}; use biliup::uploader::util::SubmitOption; use clap::Parser; @@ -101,7 +97,7 @@ async fn main() -> AppResult<()> { split_size, split_time, } => download(&url, output, split_size, split_time).await?, - Commands::Server { bind, port } => biliup_cli::run((&bind, port)).await?, + Commands::Server { bind, port, auth } => biliup_cli::run((&bind, port)).await?, Commands::List { is_pubing, pubed, diff --git a/crates/biliup-cli/src/server/api/bilibili_endpoints.rs b/crates/biliup-cli/src/server/api/bilibili_endpoints.rs index 954cd5d..0d22fd4 100644 --- a/crates/biliup-cli/src/server/api/bilibili_endpoints.rs +++ b/crates/biliup-cli/src/server/api/bilibili_endpoints.rs @@ -10,7 +10,6 @@ use bytes::Bytes; use error_stack::{Report, ResultExt}; use ormlite::Model; use std::collections::HashMap; -use tracing::info; /// B站投稿预处理端点 pub async fn archive_pre_endpoint( diff --git a/crates/biliup-cli/src/server/api/endpoints.rs b/crates/biliup-cli/src/server/api/endpoints.rs index 29789ab..e9feb08 100644 --- a/crates/biliup-cli/src/server/api/endpoints.rs +++ b/crates/biliup-cli/src/server/api/endpoints.rs @@ -6,7 +6,7 @@ use crate::server::core::download_manager::ActorHandle; use crate::server::core::downloader::Downloader; use crate::server::errors::{AppError, report_to_response}; use crate::server::infrastructure::connection_pool::ConnectionPool; -use crate::server::infrastructure::context::{Stage, Worker, WorkerStatus}; +use crate::server::infrastructure::context::{Worker, WorkerStatus}; use crate::server::infrastructure::dto::LiveStreamerResponse; use crate::server::infrastructure::models::live_streamer::{InsertLiveStreamer, LiveStreamer}; use crate::server::infrastructure::models::upload_streamer::{ @@ -19,28 +19,23 @@ use crate::server::infrastructure::repositories::{ del_streamer, get_all_streamer, get_upload_config, }; use crate::server::infrastructure::service_register::ServiceRegister; -use axum::extract::ws::{Message, Utf8Bytes, WebSocket}; -use axum::extract::{Path, Query, State, WebSocketUpgrade}; +use axum::extract::{Path, State}; use axum::http::StatusCode; use axum::response::{IntoResponse, Response}; -use axum::{Json, debug_handler}; +use axum::Json; use biliup::credential::Credential; -use chrono::{Local, Utc}; +use chrono::Utc; use clap::ValueEnum; -use error_stack::{Report, ResultExt, bail}; +use error_stack::{Report, ResultExt}; use ormlite::{Insert, Model}; use serde::Deserialize; use serde_json::json; -use std::collections::VecDeque; -use std::io; -use std::io::ErrorKind; use std::path::PathBuf; use std::sync::{Arc, RwLock}; use std::time::{Duration, UNIX_EPOCH}; use tokio::fs; -use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt, BufReader}; -use tokio::time::{MissedTickBehavior, interval}; -use tracing::{debug, error, info}; +use tokio::io::{AsyncWriteExt}; +use tracing::info; pub async fn get_streamers_endpoint( State(pool): State, @@ -92,7 +87,7 @@ pub async fn post_streamers_endpoint( .await .map_err(report_to_response)?; service_register - .add_room(&manager, live_streamers.clone(), upload_config) + .add_room(manager, live_streamers.clone(), upload_config) .await .map_err(report_to_response)?; @@ -125,7 +120,7 @@ pub async fn put_streamers_endpoint( .map_err(report_to_response)?; service_register - .add_room(&manager, streamer.clone(), upload_config) + .add_room(manager, streamer.clone(), upload_config) .await .map_err(report_to_response)?; diff --git a/crates/biliup-cli/src/server/api/ws.rs b/crates/biliup-cli/src/server/api/ws.rs index 0b837d5..f957543 100644 --- a/crates/biliup-cli/src/server/api/ws.rs +++ b/crates/biliup-cli/src/server/api/ws.rs @@ -156,7 +156,7 @@ async fn send_last_lines( let file_size = meta.len(); let file = fs::File::open(path).await?; - let mut reader = BufReader::new(file); + let reader = BufReader::new(file); let mut lines = reader.lines(); let mut buf: VecDeque = VecDeque::with_capacity(n); diff --git a/crates/biliup-cli/src/server/app.rs b/crates/biliup-cli/src/server/app.rs index 76950e5..10f9b4a 100644 --- a/crates/biliup-cli/src/server/app.rs +++ b/crates/biliup-cli/src/server/app.rs @@ -26,7 +26,7 @@ pub struct ApplicationController; impl ApplicationController { /// 启动Web服务器 - pub async fn serve(addr: &SocketAddr, service_register: ServiceRegister) -> AppResult<()> { + pub async fn serve(addr: &SocketAddr, enable_login_guard: bool, service_register: ServiceRegister) -> AppResult<()> { // 会话层配置 // 使用 tower-sessions 建立会话层,将会话作为请求扩展提供 let session_store = SqliteStore::new(service_register.pool.clone()); @@ -58,7 +58,7 @@ impl ApplicationController { let auth_layer = AuthManagerLayerBuilder::new(backend, session_layer).build(); // 构建应用程序路由 - let enable_login_guard = true; // 是否启用登录保护 + // 是否启用登录保护 let mut app = server::router::router(service_register); if enable_login_guard { app = app diff --git a/crates/biliup-cli/src/server/common/download.rs b/crates/biliup-cli/src/server/common/download.rs index 967aef6..6c3ab42 100644 --- a/crates/biliup-cli/src/server/common/download.rs +++ b/crates/biliup-cli/src/server/common/download.rs @@ -1,12 +1,10 @@ use crate::server::common::upload::UploaderMessage; -use crate::server::common::util::Recorder; use crate::server::core::downloader::{DownloadStatus, Downloader, SegmentEvent, SegmentInfo}; use crate::server::core::monitor::RoomsHandle; -use crate::server::core::plugin::{DownloadPlugin, StreamInfoExt}; +use crate::server::core::plugin::DownloadPlugin; use crate::server::errors::{AppError, AppResult}; -use crate::server::infrastructure::context::{Context, Stage, Worker, WorkerStatus}; +use crate::server::infrastructure::context::{Context, Worker, WorkerStatus}; use async_channel::{Receiver, Sender}; -use chrono::Local; use error_stack::{FutureExt, ResultExt, bail}; use std::fs; use std::path::Path; @@ -59,11 +57,10 @@ impl DownloadGuard { let rooms_handle = self.rooms_handle.clone(); let worker = self.worker.clone(); - if let Some(client) = danmaku { - if let Err(e) = client.stop().await { + if let Some(client) = danmaku + && let Err(e) = client.stop().await { error!("Error stopping danmaku client: {}", e); } - } // 确保状态更新和资源清理 rooms_handle @@ -219,18 +216,17 @@ impl SegmentEventProcessor { match event { SegmentEvent::Start { next_file_path } => { // 触发弹幕滚动保存 - if let Some(ref client) = danmaku { - if let Err(e) = client + if let Some(ref client) = danmaku + && let Err(e) = client .rolling(&next_file_path.with_extension("xml").display().to_string()) { error!("Danmaku rolling error: {}", e); } - } } SegmentEvent::Segment(event) => { // 触发弹幕滚动保存 - if let Some(ref client) = danmaku { - if let Err(e) = client.rolling( + if let Some(ref client) = danmaku + && let Err(e) = client.rolling( &event .prev_file_path .with_extension("xml") @@ -239,7 +235,6 @@ impl SegmentEventProcessor { ) { error!("Danmaku rolling error: {}", e); } - } // 异步处理事件 let processor = processor.clone(); if let Err(e) = processor.process(event) { diff --git a/crates/biliup-cli/src/server/common/upload.rs b/crates/biliup-cli/src/server/common/upload.rs index 5abb139..11081f4 100644 --- a/crates/biliup-cli/src/server/common/upload.rs +++ b/crates/biliup-cli/src/server/common/upload.rs @@ -1,20 +1,19 @@ use crate::UploadLine; use crate::server::common::util::Recorder; -use crate::server::core::downloader::{SegmentEvent, SegmentInfo}; +use crate::server::core::downloader::SegmentInfo; use crate::server::errors::{AppError, AppResult}; use crate::server::infrastructure::context::{Context, Stage, Worker, WorkerStatus}; use crate::server::infrastructure::models::InsertFileItem; use crate::server::infrastructure::models::hook_step::process_video; use crate::server::infrastructure::models::upload_streamer::UploadStreamer; use async_channel::Receiver; -use biliup::bilibili::{BiliBili, Credit, ResponseData, Studio, Video}; +use biliup::bilibili::{BiliBili, ResponseData, Studio, Video}; use biliup::client::StatelessClient; use biliup::credential::login_by_cookies; use biliup::error::Kind; use biliup::uploader::line::{Line, Probe}; use biliup::uploader::util::SubmitOption; use biliup::uploader::{VideoFile, line}; -use chrono::Local; use error_stack::ResultExt; use futures::StreamExt; use futures::stream::Inspect; @@ -73,7 +72,7 @@ where // 4. 执行后处理 if !uploaded_videos.paths.is_empty() { - execute_postprocessor(uploaded_videos.paths, &ctx).await?; + execute_postprocessor(uploaded_videos.paths, ctx).await?; } Ok(()) @@ -119,7 +118,7 @@ async fn get_upload_line(client: &StatelessClient, line: &str) -> AppResult( - mut rx: Inspect, F>, + rx: Inspect, F>, context: &UploadContext, ) -> AppResult where @@ -215,11 +214,11 @@ pub async fn submit_to_bilibili( let result = match submit_option { SubmitOption::BCutAndroid => bilibili - .submit_by_bcut_android(&studio, None) + .submit_by_bcut_android(studio, None) .await .change_context(AppError::Unknown)?, _ => bilibili - .submit_by_app(&studio, None) + .submit_by_app(studio, None) .await .change_context(AppError::Unknown)?, }; @@ -324,7 +323,7 @@ pub async fn upload( .to_str() ); info!("{line:?}"); - let video_file = VideoFile::new(&video_path).change_context_lazy(|| AppError::Unknown)?; + let video_file = VideoFile::new(video_path).change_context_lazy(|| AppError::Unknown)?; let total_size = video_file.total_size; let file_name = video_file.file_name.clone(); let uploader = line diff --git a/crates/biliup-cli/src/server/common/util.rs b/crates/biliup-cli/src/server/common/util.rs index 5e71afd..f1eddc5 100644 --- a/crates/biliup-cli/src/server/common/util.rs +++ b/crates/biliup-cli/src/server/common/util.rs @@ -1,5 +1,5 @@ use crate::server::infrastructure::models::StreamerInfo; -use chrono::{DateTime, Duration, Local}; +use chrono::{Duration, Local}; use serde::{Deserialize, Serialize}; use std::path::{Path, PathBuf}; use url::Url; diff --git a/crates/biliup-cli/src/server/core/download_manager.rs b/crates/biliup-cli/src/server/core/download_manager.rs index f6780f9..a4888c3 100644 --- a/crates/biliup-cli/src/server/core/download_manager.rs +++ b/crates/biliup-cli/src/server/core/download_manager.rs @@ -1,12 +1,10 @@ use crate::server::common::download::{DActor, DownloaderMessage}; use crate::server::common::upload::{UActor, UploaderMessage}; -use crate::server::core::downloader::Downloader; use crate::server::core::monitor::Monitor; use crate::server::core::plugin::DownloadPlugin; use crate::server::infrastructure::connection_pool::ConnectionPool; use async_channel::{Sender, bounded}; use core::fmt; -use error_stack::ResultExt; use std::sync::{Arc, Mutex}; use tokio::task::JoinHandle; /// 下载管理器 diff --git a/crates/biliup-cli/src/server/core/downloader/stream_gears.rs b/crates/biliup-cli/src/server/core/downloader/stream_gears.rs index 44d87d0..8dc0c5b 100644 --- a/crates/biliup-cli/src/server/core/downloader/stream_gears.rs +++ b/crates/biliup-cli/src/server/core/downloader/stream_gears.rs @@ -11,7 +11,6 @@ use error_stack::{ResultExt, bail}; use nom::Err; use std::path::PathBuf; use std::sync::{Arc, RwLock}; -use std::time::SystemTime; use tokio_util::sync::CancellationToken; use tracing::{debug, error, info}; diff --git a/crates/biliup-cli/src/server/core/monitor.rs b/crates/biliup-cli/src/server/core/monitor.rs index 9c3a3ac..36310d3 100644 --- a/crates/biliup-cli/src/server/core/monitor.rs +++ b/crates/biliup-cli/src/server/core/monitor.rs @@ -6,14 +6,13 @@ use crate::server::infrastructure::connection_pool::ConnectionPool; use crate::server::infrastructure::context::{Context, Stage, Worker, WorkerStatus}; use crate::server::infrastructure::models::StreamerInfo; use async_channel::{Receiver, Sender, bounded}; -use chrono::Local; use ormlite::Model; use ormlite::model::ModelBuilder; use std::sync::Arc; use std::time::Duration; use tokio::sync::oneshot; use tokio::task::JoinHandle; -use tracing::{debug, error, info}; +use tracing::{error, info}; /// 启动客户端监控循环 /// @@ -45,7 +44,7 @@ async fn start_client( .url(sql_no_id.url.clone()) .name(room.live_streamer.remark.clone()) .title(sql_no_id.title.clone()) - .date(sql_no_id.date.clone()) + .date(sql_no_id.date) .live_cover_path(sql_no_id.live_cover_path.clone()) .insert(&ctx.pool) .await @@ -76,7 +75,7 @@ async fn start_client( &suffix, ); // 修改 ctx - ctx.stream_info = stream_info; + ctx.stream_info = *stream_info; ctx.recorder = recorder; // 发送下载开始消息 if actor_handle diff --git a/crates/biliup-cli/src/server/core/plugin.rs b/crates/biliup-cli/src/server/core/plugin.rs index a926731..1392e5e 100644 --- a/crates/biliup-cli/src/server/core/plugin.rs +++ b/crates/biliup-cli/src/server/core/plugin.rs @@ -1,17 +1,15 @@ use crate::server::common::util::Recorder; use crate::server::config::Config; use crate::server::core::downloader::Downloader; -use crate::server::errors::{AppError, AppResult}; -use crate::server::infrastructure::context::{Context, Worker}; +use crate::server::errors::AppError; +use crate::server::infrastructure::context::Context; use crate::server::infrastructure::models::StreamerInfo; use async_trait::async_trait; -use chrono::{DateTime, Local}; use error_stack::Report; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::path::Path; use std::sync::Arc; -use time::OffsetDateTime; /// 流信息结构 /// 包含直播流的详细信息 @@ -33,7 +31,7 @@ pub struct StreamInfoExt { #[derive(Debug, Clone, Serialize, Deserialize)] pub enum StreamStatus { /// 正在直播,包含流信息 - Live { stream_info: StreamInfoExt }, + Live { stream_info: Box }, /// 离线状态 Offline, /// 未知状态 diff --git a/crates/biliup-cli/src/server/infrastructure/connection_pool.rs b/crates/biliup-cli/src/server/infrastructure/connection_pool.rs index ba87f60..cd4f6a9 100644 --- a/crates/biliup-cli/src/server/infrastructure/connection_pool.rs +++ b/crates/biliup-cli/src/server/infrastructure/connection_pool.rs @@ -34,6 +34,7 @@ impl ConnectionManager { std::fs::OpenOptions::new() .write(true) .create(true) + .truncate(false) .open(path) .change_context(AppError::Unknown)?; diff --git a/crates/biliup-cli/src/server/infrastructure/context.rs b/crates/biliup-cli/src/server/infrastructure/context.rs index 381f147..9138189 100644 --- a/crates/biliup-cli/src/server/infrastructure/context.rs +++ b/crates/biliup-cli/src/server/infrastructure/context.rs @@ -2,17 +2,13 @@ use crate::server::common::util::Recorder; use crate::server::config::Config; use crate::server::core::downloader::Downloader; use crate::server::core::plugin::StreamInfoExt; -use crate::server::errors::{AppError, AppResult}; use crate::server::infrastructure::connection_pool::ConnectionPool; use crate::server::infrastructure::models::live_streamer::LiveStreamer; use crate::server::infrastructure::models::upload_streamer::UploadStreamer; -use crate::server::infrastructure::repositories::{get_config, get_streamer}; use axum::http::Extensions; use biliup::client::StatelessClient; use core::fmt; -use error_stack::ResultExt; use ormlite::Model; -use serde::{Deserialize, Serialize, Serializer}; use std::sync::{Arc, RwLock}; use tracing::info; diff --git a/crates/biliup-cli/src/server/infrastructure/dto.rs b/crates/biliup-cli/src/server/infrastructure/dto.rs index d88b1fc..04d4042 100644 --- a/crates/biliup-cli/src/server/infrastructure/dto.rs +++ b/crates/biliup-cli/src/server/infrastructure/dto.rs @@ -1,6 +1,5 @@ -use crate::server::infrastructure::context::WorkerStatus; use crate::server::infrastructure::models::live_streamer::LiveStreamer; -use serde::{Deserialize, Serialize}; +use serde::Serialize; /// 直播主播响应数据传输对象 /// 包含主播信息和当前工作状态 diff --git a/crates/biliup-cli/src/server/infrastructure/models/hook_step.rs b/crates/biliup-cli/src/server/infrastructure/models/hook_step.rs index d685a36..55a1968 100644 --- a/crates/biliup-cli/src/server/infrastructure/models/hook_step.rs +++ b/crates/biliup-cli/src/server/infrastructure/models/hook_step.rs @@ -89,7 +89,7 @@ impl HookStep { let status = process.wait().await.change_context(AppError::Unknown)?; if !status.success() { bail!(AppError::Custom( - format!("Command failed with status: {}", status).into() + format!("Command failed with status: {}", status) )); } diff --git a/crates/biliup-cli/src/server/infrastructure/service_register.rs b/crates/biliup-cli/src/server/infrastructure/service_register.rs index 9127192..6adcbe1 100644 --- a/crates/biliup-cli/src/server/infrastructure/service_register.rs +++ b/crates/biliup-cli/src/server/infrastructure/service_register.rs @@ -1,9 +1,8 @@ use crate::server::config::Config; use crate::server::core::download_manager::{ActorHandle, DownloadManager}; -use crate::server::core::monitor::Monitor; use crate::server::errors::{AppError, AppResult}; use crate::server::infrastructure::connection_pool::ConnectionPool; -use crate::server::infrastructure::context::{Context, Worker, WorkerStatus}; +use crate::server::infrastructure::context::{Worker, WorkerStatus}; use crate::server::infrastructure::models::live_streamer::LiveStreamer; use crate::server::infrastructure::models::upload_streamer::UploadStreamer; use axum::extract::FromRef; diff --git a/crates/biliup-cli/src/uploader.rs b/crates/biliup-cli/src/uploader.rs index 5c2d755..4654250 100644 --- a/crates/biliup-cli/src/uploader.rs +++ b/crates/biliup-cli/src/uploader.rs @@ -5,8 +5,8 @@ use biliup::uploader::credential::{Credential, LoginInfo}; use biliup::uploader::line::Probe; use biliup::uploader::util::SubmitOption; use biliup::uploader::{VideoFile, credential, line, load_config}; -use biliup_cli::UploadLine; -use biliup_cli::server::errors::{AppError, AppResult}; +use crate::UploadLine; +use crate::server::errors::{AppError, AppResult}; use bytes::{Buf, Bytes}; use clap::ValueEnum; use dialoguer::Input; diff --git a/crates/stream-gears/Cargo.toml b/crates/stream-gears/Cargo.toml index 05e11a6..3ad3c71 100644 --- a/crates/stream-gears/Cargo.toml +++ b/crates/stream-gears/Cargo.toml @@ -9,8 +9,8 @@ name = "stream_gears" crate-type = ["cdylib", "lib"] [dependencies] -pyo3 = { version = "0.26", features = ["abi3-py38", "anyhow"] } -pythonize = { version = "0.26.0" } +pyo3 = { version = "0.27.1", features = ["abi3-py38", "anyhow"] } +pythonize = { git = "https://github.com/davidhewitt/pythonize.git", rev = "6140fe00f601f418371d969bedbcd27944a6956a" } bytes = { workspace = true } ormlite = { version = "0.24.1", features = ["sqlite", "chrono"] } rust-embed = "8.7.2" diff --git a/crates/stream-gears/src/danmaku.rs b/crates/stream-gears/src/danmaku.rs index 9280b92..15587fc 100644 --- a/crates/stream-gears/src/danmaku.rs +++ b/crates/stream-gears/src/danmaku.rs @@ -3,8 +3,6 @@ use biliup_cli::server::core::downloader::{DownloadStatus, Downloader, SegmentEv use biliup_cli::server::errors::{AppError, AppResult}; use error_stack::ResultExt; use pyo3::prelude::*; -use pyo3::types::PyDict; -use std::collections::HashMap; use std::sync::Arc; /// DanmakuClient provides Rust bindings to the Python DanmakuClient diff --git a/crates/stream-gears/src/lib.rs b/crates/stream-gears/src/lib.rs index 9427933..8dd8417 100644 --- a/crates/stream-gears/src/lib.rs +++ b/crates/stream-gears/src/lib.rs @@ -16,12 +16,14 @@ use biliup::credential::Credential; use biliup::downloader::extractor::CallbackFn; use biliup::downloader::util::{LifecycleFile, Segmentable}; use biliup::downloader::{hls, httpflv}; -use pyo3::types::PyType; +use pyo3::types::{PyList, PyType}; use std::collections::HashMap; +use std::env::args; use std::path::PathBuf; use std::str::FromStr; use std::sync::{Mutex, Once}; use std::time::Duration; +use clap::Parser; use tracing::{debug, error, info}; use tracing_subscriber::EnvFilter; @@ -461,7 +463,31 @@ fn upload( #[pyfunction] pub fn main_loop(py: Python<'_>) -> PyResult<()> { - py.detach(|| server::_main().map_err(|e| PyRuntimeError::new_err(format!("{e:?}")))) + + // 获取 Python 的 sys.argv + let sys = py.import("sys")?; + let bound = sys.getattr("argv")?; + let argv: &Bound = bound.downcast()?; + + let mut args: Vec = argv + .iter() + .map(|x| x.extract::()) + .collect::>>()?; + + // if args.len() == 1 { + // args.push("server".to_string()); + // } + match args.as_slice() { + &[] => todo!(), + &[_] => { + args.push("server".to_string()); + }, + [_, command, ..] => if command == "start" { + args[1] = "server".to_string(); + } + } + + py.detach(|| server::_main(args.as_slice()).map_err(|e| PyRuntimeError::new_err(format!("{e:?}")))) // for item in plugin_list.iter() { // // 每个元素都是一个类(type) diff --git a/crates/stream-gears/src/server.rs b/crates/stream-gears/src/server.rs index 35c3290..12366b0 100644 --- a/crates/stream-gears/src/server.rs +++ b/crates/stream-gears/src/server.rs @@ -1,4 +1,4 @@ -use crate::{DanmakuClient, construct_headers}; +use crate::{DanmakuClient, construct_headers, download}; use async_trait::async_trait; use biliup::downloader::util::Segmentable; use biliup_cli::server::app::ApplicationController; @@ -11,15 +11,14 @@ use biliup_cli::server::core::downloader::{DownloadConfig, Downloader, Downloade use biliup_cli::server::core::plugin::{DownloadPlugin, StreamInfoExt, StreamStatus}; use biliup_cli::server::errors::{AppError, AppResult}; use biliup_cli::server::infrastructure::connection_pool::ConnectionManager; -use biliup_cli::server::infrastructure::context::{Context, Worker}; +use biliup_cli::server::infrastructure::context::Context; use biliup_cli::server::infrastructure::models::StreamerInfo; use biliup_cli::server::infrastructure::repositories; use biliup_cli::server::infrastructure::repositories::get_upload_config; use biliup_cli::server::infrastructure::service_register::ServiceRegister; -use chrono::{DateTime, Local, NaiveDateTime, Utc}; +use chrono::Utc; use error_stack::{Report, ResultExt}; use fancy_regex::Regex; -use pyo3::exceptions::PyRuntimeError; use pyo3::prelude::PyDictMethods; use pyo3::prelude::{PyAnyMethods, PyListMethods, PyModule}; use pyo3::types::PyDict; @@ -32,8 +31,12 @@ use std::net::ToSocketAddrs; use std::ops::Deref; use std::path::PathBuf; use std::sync::{Arc, LazyLock, RwLock}; -use time::OffsetDateTime; +use clap::Parser; use tracing::{debug, info}; +use biliup::uploader::util::SubmitOption; +use biliup_cli::cli::{Cli, Commands}; +use biliup_cli::downloader::generate_json; +use biliup_cli::uploader::{append, list, login, renew, show, upload_by_command, upload_by_config}; #[derive(Debug)] pub struct PyPlugin { @@ -82,7 +85,7 @@ impl DownloadPlugin for PyPlugin { Arc::new(DanmakuClient::new(Arc::new(danmaku))) as Arc; ctx.extension.insert(danmaku); } - Ok(StreamStatus::Live { stream_info: info }) + Ok(StreamStatus::Live { stream_info: Box::new(info) }) } None => Ok(StreamStatus::Offline), } @@ -102,7 +105,7 @@ impl DownloadPlugin for PyPlugin { segment_time: config.segment_time.or_else(default_segment_time), file_size: Some(config.file_size), // 2GB headers: stream_info.stream_headers.clone(), - recorder: recorder, + recorder, // output_dir: PathBuf::from("./downloads") output_dir: PathBuf::from("."), }; @@ -349,44 +352,129 @@ fn cfg_arc() -> &'static Arc> { } #[tokio::main] -pub(crate) async fn _main() -> AppResult<()> { - info!( +pub(crate) async fn _main(args: &[String]) -> AppResult<()> { + + let cli = Cli::try_parse_from(args).change_context(AppError::Unknown)?; + + match cli.command { + Commands::Login => login(cli.user_cookie, cli.proxy.as_deref()).await?, + Commands::Renew => { + renew(cli.user_cookie, cli.proxy.as_deref()).await?; + } + Commands::Upload { + video_path, + config: None, + line, + limit, + studio, + submit, + } => { + upload_by_command( + studio, + cli.user_cookie, + video_path, + line, + limit, + submit.unwrap_or(SubmitOption::App), + cli.proxy.as_deref(), + ) + .await? + } + Commands::Upload { + video_path: _, + config: Some(config), + submit, + .. + } => { + upload_by_config(config, cli.user_cookie, submit, cli.proxy.as_deref()).await?; + } + Commands::Append { + video_path, + vid, + line, + limit, + studio: _, + submit, + } => { + append( + cli.user_cookie, + vid, + video_path, + line, + limit, + submit.unwrap_or(SubmitOption::App), + cli.proxy.as_deref(), + ) + .await? + } + Commands::Show { vid } => show(cli.user_cookie, vid, cli.proxy.as_deref()).await?, + Commands::DumpFlv { file_name } => generate_json(file_name)?, + Commands::Download { + url, + output, + split_size, + split_time, + } => biliup_cli::downloader::download(&url, output, split_size, split_time).await?, + Commands::Server { bind, port, auth } => { + info!( "environment loaded and configuration parsed, initializing Postgres connection and running migrations..." ); - let conn_pool = ConnectionManager::new_pool("data/data.sqlite3") - .await - .expect("could not initialize the database connection pool"); + let conn_pool = ConnectionManager::new_pool("data/data.sqlite3") + .await + .expect("could not initialize the database connection pool"); - *CONFIG.write().unwrap() = repositories::get_config(&conn_pool).await?; - let actor_handle = Arc::new(ActorHandle::new( - CONFIG.read().unwrap().pool1_size, - CONFIG.read().unwrap().pool2_size, - )); - let vec = from_py(actor_handle.clone()).unwrap(); + *CONFIG.write().unwrap() = repositories::get_config(&conn_pool).await?; + let actor_handle = Arc::new(ActorHandle::new( + CONFIG.read().unwrap().pool1_size, + CONFIG.read().unwrap().pool2_size, + )); + let vec = from_py(actor_handle.clone()).unwrap(); - let service_register = ServiceRegister::new(conn_pool, CONFIG.clone(), actor_handle, vec); + let service_register = ServiceRegister::new(conn_pool, CONFIG.clone(), actor_handle, vec); - let all_streamer = repositories::get_all_streamer(&service_register.pool).await?; + let all_streamer = repositories::get_all_streamer(&service_register.pool).await?; - for streamer in all_streamer { - // workers.push(Arc::new(Worker::new(streamer.id, service_register.pool.clone()))); - if let Some(manager) = service_register.get_manager(&streamer.url) { - let upload_config = get_upload_config(&service_register.pool, streamer.id).await?; - let _ = service_register - .add_room(&manager, streamer, upload_config) - .await?; - }; - } + for streamer in all_streamer { + // workers.push(Arc::new(Worker::new(streamer.id, service_register.pool.clone()))); + if let Some(manager) = service_register.get_manager(&streamer.url) { + let upload_config = get_upload_config(&service_register.pool, streamer.id).await?; + let _ = service_register + .add_room(manager, streamer, upload_config) + .await?; + }; + } + + info!("migrations successfully ran, initializing axum server..."); + let addr = (bind, port); + let addr = addr + .to_socket_addrs() + .change_context(AppError::Unknown)? + .next() + .unwrap(); + ApplicationController::serve(&addr, auth, service_register) + .await + .attach("could not initialize application routes")?; + // biliup_cli::run((&bind, port)).await? + }, + Commands::List { + is_pubing, + pubed, + not_pubed, + from_page, + max_pages, + } => { + list( + cli.user_cookie, + is_pubing, + pubed, + not_pubed, + cli.proxy.as_deref(), + from_page, + max_pages, + ) + .await? + } + }; - info!("migrations successfully ran, initializing axum server..."); - let addr = ("0.0.0.0", 19159); - let addr = addr - .to_socket_addrs() - .change_context(AppError::Unknown)? - .next() - .unwrap(); - ApplicationController::serve(&addr, service_register) - .await - .attach("could not initialize application routes")?; Ok(()) } diff --git a/crates/stream-gears/src/uploader.rs b/crates/stream-gears/src/uploader.rs index eb7bb9b..dd648db 100644 --- a/crates/stream-gears/src/uploader.rs +++ b/crates/stream-gears/src/uploader.rs @@ -1,11 +1,4 @@ -use biliup::client::StatelessClient; -use biliup::error::Kind; use biliup::uploader::bilibili::{Credit, ResponseData, Studio}; -use biliup::uploader::credential::login_by_cookies; -use biliup::uploader::line::Probe; -use biliup::uploader::util::SubmitOption; -use biliup::uploader::{VideoFile, line}; -use futures::StreamExt; use pyo3::prelude::*; use pyo3::pyclass; @@ -16,9 +9,6 @@ use bon::Builder; use error_stack::ResultExt; use std::collections::HashMap; use std::path::PathBuf; -use std::str::FromStr; -use std::time::Instant; -use tracing::info; #[pyclass] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] @@ -40,11 +30,11 @@ pub enum UploadLine { Alia, } -impl Into for UploadLine { - fn into(self) -> biliup_cli::UploadLine { +impl From for biliup_cli::UploadLine { + fn from(val: UploadLine) -> Self { use UploadLine as P; use biliup_cli::UploadLine as C; - match self { + match val { P::Bldsa => C::Bldsa, P::Cnbldsa => C::Cnbldsa, P::Andsa => C::Andsa, @@ -190,5 +180,5 @@ pub async fn upload( studio.cover = url; } - Ok(submit_to_bilibili(&bilibili, &studio, submit).await?) + submit_to_bilibili(&bilibili, &studio, submit).await } diff --git a/tauri-app/src-tauri/src/lib.rs b/tauri-app/src-tauri/src/lib.rs index 9e60358..4559d35 100644 --- a/tauri-app/src-tauri/src/lib.rs +++ b/tauri-app/src-tauri/src/lib.rs @@ -51,7 +51,6 @@ fn spawn_and_monitor_sidecar(app_handle: tauri::AppHandle) -> Result<(), String> let exe_dir = exe_path.parent().unwrap(); println!("[tauri] Sidecar directory: {}", exe_dir.display()); let (mut rx, child) = sidecar_command - .args(["-P", "19159"]) .current_dir(exe_dir) // .env("PYTHONUTF8", "1") .spawn()