Refactor and clean up unused imports and code
Removed unused imports and redundant code across multiple modules to improve code clarity and maintainability. Updated function signatures in flv_parser for lifetime correctness. Added Drop implementation for ActorHandle to ensure background tasks are aborted on drop. Simplified logic in uploader login functions and improved pattern matching in endpoints. Minor code style and comment cleanups throughout the codebase.
This commit is contained in:
1 parent
fb4dc2b50a
commit
84c798a8d7
17 files changed
+65
-100
No files matched your search
@@ -7,13 +7,5 @@ pub mod infrastructure;
|
||||
mod router;
|
||||
pub mod util;
|
||||
|
||||
use error_stack::ResultExt;
|
||||
use futures::TryFutureExt;
|
||||
|
||||
use std::net::ToSocketAddrs;
|
||||
// use tokio::sync::mpsc::Receiver;
|
||||
use crate::server::errors::{AppError, AppResult};
|
||||
use crate::server::infrastructure::connection_pool::ConnectionManager;
|
||||
use crate::server::infrastructure::repositories;
|
||||
use crate::server::infrastructure::service_register::ServiceRegister;
|
||||
use tracing::info;
|
||||
@@ -3,7 +3,7 @@ use crate::server::infrastructure::connection_pool::ConnectionPool;
|
||||
use crate::server::infrastructure::models::Configuration;
|
||||
use axum::extract::{Query, State};
|
||||
use axum::response::Response;
|
||||
use axum::{Extension, Json};
|
||||
use axum::Json;
|
||||
use biliup::client::StatelessClient;
|
||||
use biliup::uploader::credential::login_by_cookies;
|
||||
use bytes::Bytes;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::server::config::Config;
|
||||
use crate::server::errors::{AppError, AppResult, report_to_response};
|
||||
use crate::server::errors::{AppError, report_to_response};
|
||||
use crate::server::infrastructure::connection_pool::ConnectionPool;
|
||||
use crate::server::infrastructure::context::Worker;
|
||||
use crate::server::infrastructure::dto::LiveStreamerResponse;
|
||||
@@ -12,8 +12,8 @@ use crate::server::infrastructure::service_register::ServiceRegister;
|
||||
use axum::extract::{Path, State};
|
||||
use axum::http::StatusCode;
|
||||
use axum::response::{IntoResponse, Response};
|
||||
use axum::{Json, debug_handler};
|
||||
use biliup::credential::{Credential, LoginInfo};
|
||||
use axum::Json;
|
||||
use biliup::credential::Credential;
|
||||
use error_stack::{Report, ResultExt};
|
||||
use ormlite::{Insert, Model};
|
||||
use serde_json::json;
|
||||
@@ -65,7 +65,7 @@ pub async fn post_streamers_endpoint(
|
||||
};
|
||||
let monitor = manager.ensure_monitor();
|
||||
|
||||
/// You can insert the model directly.
|
||||
// You can insert the model directly.
|
||||
let live_streamers = payload
|
||||
.insert(&pool)
|
||||
.await
|
||||
@@ -113,7 +113,6 @@ pub async fn put_streamers_endpoint(
|
||||
pub async fn delete_streamers_endpoint(
|
||||
State(service_register): State<ServiceRegister>,
|
||||
State(pool): State<ConnectionPool>,
|
||||
State(workers): State<Arc<RwLock<Vec<Arc<Worker>>>>>,
|
||||
Path(id): Path<i64>,
|
||||
) -> Result<Json<LiveStreamer>, Response> {
|
||||
service_register
|
||||
@@ -414,12 +413,11 @@ pub async fn get_videos() -> Result<Json<Vec<serde_json::Value>>, Response> {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(ext) = path.extension().and_then(|e| e.to_str()) {
|
||||
if media_extensions
|
||||
if let Some(ext) = path.extension().and_then(|e| e.to_str())
|
||||
&& media_extensions
|
||||
.iter()
|
||||
.any(|allowed| &ext == &allowed.trim_start_matches('.'))
|
||||
{
|
||||
if let Ok(metadata) = entry.metadata().await {
|
||||
.any(|allowed| ext == allowed.trim_start_matches('.'))
|
||||
&& let Ok(metadata) = entry.metadata().await {
|
||||
let mtime = metadata
|
||||
.modified()
|
||||
.ok()
|
||||
@@ -435,8 +433,6 @@ pub async fn get_videos() -> Result<Json<Vec<serde_json::Value>>, Response> {
|
||||
}));
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Json(file_list))
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use biliup::client::StatelessClient;
|
||||
|
||||
use axum::{Extension, http};
|
||||
use axum::http;
|
||||
|
||||
use crate::server;
|
||||
use crate::server::api::auth;
|
||||
|
||||
@@ -3,9 +3,6 @@ use crate::server::errors::{AppError, AppResult};
|
||||
use crate::server::infrastructure::models::hook_step::HookStep;
|
||||
use error_stack::bail;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cell::LazyCell;
|
||||
use std::ops::Deref;
|
||||
use std::sync::{Arc, LazyLock, OnceLock, RwLock};
|
||||
use std::{collections::HashMap, path::Path, path::PathBuf};
|
||||
|
||||
#[derive(bon::Builder, Debug, Clone, Serialize, Deserialize)]
|
||||
@@ -315,9 +312,6 @@ fn default_pool1_size() -> u32 {
|
||||
fn default_pool2_size() -> u32 {
|
||||
3
|
||||
}
|
||||
fn default_check_sourcecode() -> u64 {
|
||||
15
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn load_or_create<P: AsRef<Path>>(path: P) -> AppResult<Self> {
|
||||
|
||||
@@ -256,7 +256,7 @@ impl UActor {
|
||||
let streamer = worker.get_streamer().await.unwrap();
|
||||
if let Some(post_processor) = streamer.postprocessor {
|
||||
for video_path in &video_paths {
|
||||
process_video(video_path, &post_processor)
|
||||
let _ = process_video(video_path, &post_processor)
|
||||
.await
|
||||
.map_err(|e| error!(e=?e));
|
||||
}
|
||||
@@ -361,3 +361,16 @@ pub enum DownloaderMessage {
|
||||
Arc<RoomsHandle>,
|
||||
),
|
||||
}
|
||||
|
||||
impl Drop for ActorHandle {
|
||||
fn drop(&mut self) {
|
||||
// 发送端随 ActorHandle 一起被 drop,会关闭通道(如果没有其他 sender 克隆)。
|
||||
// 为避免 tokio 任务在后台“挂着”,这里直接 abort。
|
||||
for h in &self.d_kills {
|
||||
h.abort();
|
||||
}
|
||||
for h in &self.u_kills {
|
||||
h.abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,10 @@
|
||||
pub mod ffmpeg_downloader;
|
||||
pub mod stream_gears;
|
||||
|
||||
use crate::server::core::download_manager::UploaderMessage;
|
||||
use crate::server::infrastructure::context::Worker;
|
||||
use async_channel::Sender;
|
||||
use async_trait::async_trait;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tokio::io::AsyncBufReadExt;
|
||||
|
||||
/// 下载器配置
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
use crate::server::core::download_manager::UploaderMessage;
|
||||
use crate::server::core::downloader;
|
||||
use crate::server::core::downloader::{
|
||||
DownloadConfig, DownloadStatus, Downloader, DownloaderType, SegmentEvent,
|
||||
};
|
||||
use crate::server::infrastructure::context::Worker;
|
||||
use async_channel::{Sender, bounded};
|
||||
use async_trait::async_trait;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Stdio;
|
||||
@@ -12,7 +9,7 @@ use std::sync::Arc;
|
||||
use tokio::io::{AsyncBufReadExt, BufReader};
|
||||
use tokio::process::Command;
|
||||
use tokio::sync::RwLock;
|
||||
use tracing::{info, warn};
|
||||
use tracing::info;
|
||||
|
||||
/// FFmpeg下载器实现
|
||||
pub struct FfmpegDownloader {
|
||||
@@ -199,7 +196,6 @@ impl FfmpegDownloader {
|
||||
}
|
||||
};
|
||||
// let (tx, rx) = bounded(16);
|
||||
let i = 0;
|
||||
// 分段回调
|
||||
let segment_callback = |event: SegmentEvent| {
|
||||
println!("New segment: {:?}", event.file_path);
|
||||
@@ -246,7 +242,7 @@ impl FfmpegDownloader {
|
||||
callback: Box<dyn Fn(SegmentEvent) + Send + Sync + 'static>,
|
||||
) -> Result<DownloadStatus, Box<dyn std::error::Error>> {
|
||||
let args = self.build_ffmpeg_args_internal_segment();
|
||||
let output_pattern = self.output_dir.join("%d.{}");
|
||||
let _output_pattern = self.output_dir.join("%d.{}");
|
||||
|
||||
let mut cmd = Command::new("ffmpeg");
|
||||
cmd.args(&args)
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
use crate::server::core::download_manager::UploaderMessage;
|
||||
use crate::server::core::downloader::{DownloadStatus, Downloader, SegmentEvent};
|
||||
use crate::server::infrastructure::context::Worker;
|
||||
use async_channel::{Sender, bounded};
|
||||
use async_trait::async_trait;
|
||||
use axum::http::HeaderMap;
|
||||
use biliup::client::StatelessClient;
|
||||
@@ -13,7 +10,7 @@ use nom::Err;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::time::SystemTime;
|
||||
use tracing::{debug, error, info, warn};
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
// 具体下载器实现
|
||||
pub struct StreamGears {
|
||||
@@ -36,7 +33,7 @@ impl StreamGears {
|
||||
Self {
|
||||
url: url.into(),
|
||||
header_map,
|
||||
file_name: file_name,
|
||||
file_name,
|
||||
segment,
|
||||
proxy,
|
||||
status: Arc::new(RwLock::new(DownloadStatus::Downloading)),
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
use crate::server::core::download_manager::{ActorHandle, DownloadManager};
|
||||
use crate::server::core::downloader::ffmpeg_downloader::FfmpegDownloader;
|
||||
use crate::server::core::downloader::stream_gears::StreamGears;
|
||||
use crate::server::core::downloader::{DownloadConfig, Downloader, DownloaderType};
|
||||
use crate::server::core::downloader::Downloader;
|
||||
use crate::server::errors::{AppError, AppResult};
|
||||
use crate::server::infrastructure::context::Worker;
|
||||
use crate::server::util::{Recorder, media_ext_from_url, parse_time};
|
||||
use async_trait::async_trait;
|
||||
use biliup::downloader::util::Segmentable;
|
||||
use error_stack::{Report, ResultExt};
|
||||
use error_stack::Report;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use std::path::Path;
|
||||
use time::OffsetDateTime;
|
||||
use tracing::{debug, info};
|
||||
|
||||
// Stream information structures
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
||||
@@ -15,10 +15,10 @@ impl ConnectionManager {
|
||||
if let Some(parent) = Path::new(path).parent() {
|
||||
std::fs::create_dir_all(parent)
|
||||
.change_context(AppError::Unknown)
|
||||
.attach_lazy(|| path.to_string())?; // 创建 data/ 目录
|
||||
.attach_with(|| path.to_string())?; // 创建 data/ 目录
|
||||
}
|
||||
let db_url = format!("sqlite://{path}");
|
||||
/// Start by making a database connection.
|
||||
// Start by making a database connection.
|
||||
std::fs::OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
@@ -32,8 +32,7 @@ impl ConnectionManager {
|
||||
"error while initializing the database connection pool".to_string(),
|
||||
))?;
|
||||
|
||||
/// Query builder syntax closely follows SQL syntax, translated into chained function calls.
|
||||
|
||||
// Query builder syntax closely follows SQL syntax, translated into chained function calls.
|
||||
info!("migrations enabled, running...");
|
||||
sqlx::migrate!()
|
||||
.run(&pool)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::server::config::Config;
|
||||
use crate::server::errors::{AppError, AppResult};
|
||||
use crate::server::infrastructure::connection_pool::ConnectionPool;
|
||||
use crate::server::infrastructure::models::{Configuration, LiveStreamer, UploadStreamer};
|
||||
use crate::server::infrastructure::models::{LiveStreamer, UploadStreamer};
|
||||
use crate::server::infrastructure::repositories::{get_config, get_streamer};
|
||||
use biliup::client::StatelessClient;
|
||||
use error_stack::ResultExt;
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
use crate::server::config;
|
||||
use crate::server::config::Config;
|
||||
use crate::server::core::download_manager::{ActorHandle, DownloadManager};
|
||||
use crate::server::core::monitor::Monitor;
|
||||
use crate::server::core::plugin;
|
||||
use crate::server::errors::{AppError, AppResult};
|
||||
use crate::server::infrastructure::connection_pool::ConnectionPool;
|
||||
use crate::server::infrastructure::context::{Context, Worker};
|
||||
use crate::server::infrastructure::repositories;
|
||||
use axum::extract::FromRef;
|
||||
use biliup::client::StatelessClient;
|
||||
use biliup::credential::Credential;
|
||||
use error_stack::bail;
|
||||
use ormlite::Model;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use tracing::info;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::server::errors::{AppError, AppResult};
|
||||
use crate::server::infrastructure::connection_pool::ConnectionPool;
|
||||
use axum_login::{AuthUser, AuthnBackend, UserId};
|
||||
use error_stack::FutureExt;
|
||||
use error_stack::{ResultExt, bail};
|
||||
use password_auth::{generate_hash, verify_password};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -344,10 +344,10 @@ pub async fn login_by_password(credential: Credential) -> AppResult<LoginInfo> {
|
||||
.with_prompt("请输入密码")
|
||||
.interact()
|
||||
.change_context_lazy(|| AppError::Unknown)?;
|
||||
Ok(credential
|
||||
credential
|
||||
.login_by_password(&username, &password)
|
||||
.await
|
||||
.change_context_lazy(|| AppError::Unknown)?)
|
||||
.change_context_lazy(|| AppError::Unknown)
|
||||
}
|
||||
|
||||
pub async fn login_by_sms(credential: Credential) -> AppResult<LoginInfo> {
|
||||
@@ -384,10 +384,10 @@ pub async fn login_by_sms(credential: Credential) -> AppResult<LoginInfo> {
|
||||
.interact_text()
|
||||
.change_context_lazy(|| AppError::Unknown)?;
|
||||
// println!("{}", payload);
|
||||
Ok(credential
|
||||
credential
|
||||
.login_by_sms(input, res)
|
||||
.await
|
||||
.change_context_lazy(|| AppError::Unknown)?)
|
||||
.change_context_lazy(|| AppError::Unknown)
|
||||
}
|
||||
|
||||
pub async fn login_by_qrcode(credential: Credential) -> AppResult<LoginInfo> {
|
||||
@@ -415,10 +415,10 @@ pub async fn login_by_qrcode(credential: Credential) -> AppResult<LoginInfo> {
|
||||
);
|
||||
// Save the image.
|
||||
image.save("qrcode.png").unwrap();
|
||||
Ok(credential
|
||||
credential
|
||||
.login_by_qrcode(value)
|
||||
.await
|
||||
.change_context_lazy(|| AppError::Unknown)?)
|
||||
.change_context_lazy(|| AppError::Unknown)
|
||||
}
|
||||
|
||||
pub async fn login_by_browser(credential: Credential) -> AppResult<LoginInfo> {
|
||||
@@ -433,10 +433,10 @@ pub async fn login_by_browser(credential: Credential) -> AppResult<LoginInfo> {
|
||||
.ok_or_else(|| AppError::Custom(value.to_string()))?
|
||||
);
|
||||
println!("请复制此链接至浏览器中完成登录");
|
||||
Ok(credential
|
||||
credential
|
||||
.login_by_qrcode(value)
|
||||
.await
|
||||
.change_context_lazy(|| AppError::Unknown)?)
|
||||
.change_context_lazy(|| AppError::Unknown)
|
||||
}
|
||||
|
||||
pub async fn login_by_web_cookies(credential: Credential) -> AppResult<LoginInfo> {
|
||||
@@ -448,10 +448,10 @@ pub async fn login_by_web_cookies(credential: Credential) -> AppResult<LoginInfo
|
||||
.with_prompt("请输入bili_jct")
|
||||
.interact_text()
|
||||
.change_context_lazy(|| AppError::Unknown)?;
|
||||
Ok(credential
|
||||
credential
|
||||
.login_by_web_cookies(&sess_data, &bili_jct)
|
||||
.await
|
||||
.change_context_lazy(|| AppError::Unknown)?)
|
||||
.change_context_lazy(|| AppError::Unknown)
|
||||
}
|
||||
|
||||
pub async fn login_by_webqr_cookies(credential: Credential) -> AppResult<LoginInfo> {
|
||||
@@ -463,10 +463,10 @@ pub async fn login_by_webqr_cookies(credential: Credential) -> AppResult<LoginIn
|
||||
.with_prompt("请输入DedeUserID")
|
||||
.interact_text()
|
||||
.change_context_lazy(|| AppError::Unknown)?;
|
||||
Ok(credential
|
||||
credential
|
||||
.login_by_web_qrcode(&sess_data, &dede_user_id)
|
||||
.await
|
||||
.change_context_lazy(|| AppError::Unknown)?)
|
||||
.change_context_lazy(|| AppError::Unknown)
|
||||
}
|
||||
|
||||
impl From<Progressbar> for Body {
|
||||
|
||||
@@ -90,7 +90,7 @@ pub fn tag_header(input: &[u8]) -> IResult<&[u8], TagHeader> {
|
||||
.parse(input)
|
||||
}
|
||||
|
||||
pub fn complete_tag(input: &[u8]) -> IResult<&[u8], Tag> {
|
||||
pub fn complete_tag(input: &[u8]) -> IResult<&[u8], Tag<'_>> {
|
||||
flat_map(pair(tag_type, be_u24), |(tag_type, data_size)| {
|
||||
map(
|
||||
(
|
||||
@@ -194,7 +194,7 @@ pub struct AACAudioPacket<'a> {
|
||||
pub aac_data: &'a [u8],
|
||||
}
|
||||
|
||||
pub fn aac_audio_packet(input: &[u8], size: usize) -> IResult<&[u8], AACAudioPacket> {
|
||||
pub fn aac_audio_packet(input: &[u8], size: usize) -> IResult<&[u8], AACAudioPacket<'_>> {
|
||||
if input.len() < size {
|
||||
return Err(Err::Incomplete(Needed::new(size)));
|
||||
}
|
||||
@@ -232,7 +232,7 @@ pub struct AudioData<'a> {
|
||||
pub sound_data: &'a [u8],
|
||||
}
|
||||
|
||||
pub fn audio_data(input: &[u8], size: usize) -> IResult<&[u8], AudioData> {
|
||||
pub fn audio_data(input: &[u8], size: usize) -> IResult<&[u8], AudioData<'_>> {
|
||||
if input.len() < size {
|
||||
return Err(Err::Incomplete(Needed::new(size)));
|
||||
}
|
||||
@@ -441,7 +441,7 @@ pub struct AVCVideoPacket<'a> {
|
||||
pub avc_data: &'a [u8],
|
||||
}
|
||||
|
||||
pub fn avc_video_packet(input: &[u8], size: usize) -> IResult<&[u8], AVCVideoPacket> {
|
||||
pub fn avc_video_packet(input: &[u8], size: usize) -> IResult<&[u8], AVCVideoPacket<'_>> {
|
||||
if input.len() < size {
|
||||
return Err(Err::Incomplete(Needed::new(size)));
|
||||
}
|
||||
@@ -470,7 +470,7 @@ pub struct VideoData<'a> {
|
||||
pub video_data: &'a [u8],
|
||||
}
|
||||
|
||||
pub fn video_data(input: &[u8], size: usize) -> IResult<&[u8], VideoData> {
|
||||
pub fn video_data(input: &[u8], size: usize) -> IResult<&[u8], VideoData<'_>> {
|
||||
if input.len() < size {
|
||||
return Err(Err::Incomplete(Needed::new(size)));
|
||||
}
|
||||
@@ -600,7 +600,7 @@ pub struct ScriptDataDate {
|
||||
#[allow(non_upper_case_globals)]
|
||||
static script_data_name_tag: &[u8] = &[2];
|
||||
|
||||
pub fn script_data(input: &[u8]) -> IResult<&[u8], ScriptData> {
|
||||
pub fn script_data(input: &[u8]) -> IResult<&[u8], ScriptData<'_>> {
|
||||
// Must start with a string, i.e. 2
|
||||
map(
|
||||
(
|
||||
@@ -613,7 +613,7 @@ pub fn script_data(input: &[u8]) -> IResult<&[u8], ScriptData> {
|
||||
.parse(input)
|
||||
}
|
||||
|
||||
pub fn script_data_value(input: &[u8]) -> IResult<&[u8], ScriptDataValue> {
|
||||
pub fn script_data_value(input: &[u8]) -> IResult<&[u8], ScriptDataValue<'_>> {
|
||||
be_u8(input).and_then(|v| match v {
|
||||
(i, 0) => map(be_f64, ScriptDataValue::Number).parse(i),
|
||||
(i, 1) => map(be_u8, |n| ScriptDataValue::Boolean(n != 0)).parse(i),
|
||||
@@ -631,11 +631,11 @@ pub fn script_data_value(input: &[u8]) -> IResult<&[u8], ScriptDataValue> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn script_data_objects(input: &[u8]) -> IResult<&[u8], Vec<ScriptDataObject>> {
|
||||
pub fn script_data_objects(input: &[u8]) -> IResult<&[u8], Vec<ScriptDataObject<'_>>> {
|
||||
terminated(many0(script_data_object), script_data_object_end).parse(input)
|
||||
}
|
||||
|
||||
pub fn script_data_object(input: &[u8]) -> IResult<&[u8], ScriptDataObject> {
|
||||
pub fn script_data_object(input: &[u8]) -> IResult<&[u8], ScriptDataObject<'_>> {
|
||||
map(
|
||||
pair(script_data_string, script_data_value),
|
||||
|(name, data)| ScriptDataObject { name, data },
|
||||
@@ -669,13 +669,13 @@ pub fn script_data_date(input: &[u8]) -> IResult<&[u8], ScriptDataDate> {
|
||||
.parse(input)
|
||||
}
|
||||
|
||||
pub fn script_data_ecma_array(input: &[u8]) -> IResult<&[u8], Vec<ScriptDataObject>> {
|
||||
pub fn script_data_ecma_array(input: &[u8]) -> IResult<&[u8], Vec<ScriptDataObject<'_>>> {
|
||||
map(pair(be_u32, script_data_objects), |(_, data_objects)| {
|
||||
data_objects
|
||||
})
|
||||
.parse(input)
|
||||
}
|
||||
|
||||
pub fn script_data_strict_array(input: &[u8]) -> IResult<&[u8], Vec<ScriptDataValue>> {
|
||||
pub fn script_data_strict_array(input: &[u8]) -> IResult<&[u8], Vec<ScriptDataValue<'_>>> {
|
||||
flat_map(be_u32, |o| many_m_n(1, o as usize, script_data_value)).parse(input)
|
||||
}
|
||||
@@ -2,7 +2,6 @@ use crate::construct_headers;
|
||||
use async_trait::async_trait;
|
||||
use biliup::downloader::util::Segmentable;
|
||||
use biliup_cli::server::app::ApplicationController;
|
||||
use biliup_cli::server::config;
|
||||
use biliup_cli::server::config::Config;
|
||||
use biliup_cli::server::core::download_manager::{ActorHandle, DownloadManager};
|
||||
use biliup_cli::server::core::downloader::ffmpeg_downloader::FfmpegDownloader;
|
||||
@@ -17,15 +16,13 @@ use biliup_cli::server::infrastructure::service_register::ServiceRegister;
|
||||
use biliup_cli::server::util::{Recorder, media_ext_from_url, parse_time};
|
||||
use error_stack::{Report, ResultExt};
|
||||
use fancy_regex::Regex;
|
||||
use futures::TryFutureExt;
|
||||
use pyo3::exceptions::PyRuntimeError;
|
||||
use pyo3::prelude::PyDictMethods;
|
||||
use pyo3::prelude::{PyAnyMethods, PyListMethods, PyModule};
|
||||
use pyo3::sync::OnceLockExt;
|
||||
use pyo3::types::PyDict;
|
||||
use pyo3::types::{PyList, PyType};
|
||||
use pyo3::{Bound, Py, PyAny, PyResult, Python};
|
||||
use pyo3::{FromPyObject, pyclass, pyfunction, pymethods};
|
||||
use pyo3::{pyclass, pyfunction, pymethods};
|
||||
use pythonize::pythonize;
|
||||
use std::collections::HashMap;
|
||||
use std::net::ToSocketAddrs;
|
||||
@@ -170,7 +167,7 @@ async fn call_via_threads(obj: Arc<Py<PyType>>, url: &str) -> PyResult<Option<St
|
||||
let res = fut.call_method0("result")?;
|
||||
let is_live = res.unbind().extract(py)?;
|
||||
let info = if is_live {
|
||||
Some(stream_info_from_py(py, &instance)?)
|
||||
Some(stream_info_from_py(&instance)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -188,7 +185,7 @@ pub fn from_py(actor_handle: Arc<ActorHandle>) -> PyResult<Vec<DownloadManager>>
|
||||
// 获取 Plugin 类
|
||||
let plugin_class = decorators.getattr("Plugin")?;
|
||||
|
||||
let instance = plugin_class.call1((plugins,))?;
|
||||
let _instance = plugin_class.call1((plugins,))?;
|
||||
|
||||
// 如果要获取类属性(而不是实例属性)
|
||||
let bound = plugin_class.getattr("download_plugins")?;
|
||||
@@ -214,14 +211,14 @@ pub fn from_py(actor_handle: Arc<ActorHandle>) -> PyResult<Vec<DownloadManager>>
|
||||
|
||||
/// 从 Python 的 `self`(Bound<PyAny>)与 start_time / end_time 构造 StreamInfo
|
||||
/// end_time 的语义与 Python 中一致:若未提供或为“假值”,则使用 time.localtime()
|
||||
pub fn stream_info_from_py(py: Python<'_>, self_obj: &Bound<'_, PyAny>) -> PyResult<StreamInfo> {
|
||||
pub fn stream_info_from_py(self_obj: &Bound<'_, PyAny>) -> PyResult<StreamInfo> {
|
||||
// 从 self 上获取属性并抽取为 Rust 类型
|
||||
let name: String = self_obj.getattr("fname")?.extract()?;
|
||||
let url: String = self_obj.getattr("url")?.extract()?;
|
||||
let raw_stream_url: String = self_obj.getattr("raw_stream_url")?.extract()?;
|
||||
let title: String = self_obj.getattr("room_title")?.extract()?;
|
||||
let live_cover_path: Option<String> = self_obj.getattr("live_cover_path")?.extract()?;
|
||||
let is_download: bool = self_obj.getattr("is_download")?.extract()?;
|
||||
let _is_download: bool = self_obj.getattr("is_download")?.extract()?;
|
||||
let platform: String = self_obj.getattr("platform")?.extract()?;
|
||||
let stream_headers: HashMap<String, String> = self_obj.getattr("stream_headers")?.extract()?;
|
||||
self_obj.call_method1("update_headers", (&stream_headers,))?;
|
||||
@@ -292,7 +289,7 @@ impl ConfigState {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
pub fn config_bindings(py: Python<'_>) -> PyResult<ConfigState> {
|
||||
pub fn config_bindings() -> PyResult<ConfigState> {
|
||||
let state = ConfigState {
|
||||
map: cfg_arc().clone(),
|
||||
};
|
||||
@@ -308,7 +305,7 @@ pub static CONFIG: LazyLock<Arc<RwLock<Config>>> = LazyLock::new(|| {
|
||||
});
|
||||
|
||||
fn cfg_arc() -> &'static Arc<RwLock<Config>> {
|
||||
&*CONFIG
|
||||
&CONFIG
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
||||
Reference in new issue
Block a user