157 lines
4.2 KiB
Rust
157 lines
4.2 KiB
Rust
use crate::model::data::drive::PackFileBaseInput;
|
|
use crate::model::processing::PackResult;
|
|
use crate::model::{PackType, PackingContext};
|
|
use magnetar_calckey_model::ck;
|
|
use magnetar_sdk::types::drive::{DriveFileBase, PackDriveFileBase};
|
|
use magnetar_sdk::types::Id;
|
|
use magnetar_sdk::{Packed, Required};
|
|
use tracing::warn;
|
|
use url::Url;
|
|
|
|
pub struct DriveModel;
|
|
|
|
impl DriveModel {
|
|
pub fn media_proxy_url(
|
|
&self,
|
|
ctx: &PackingContext,
|
|
url: &str,
|
|
is_thumbnail: bool,
|
|
) -> Option<Url> {
|
|
if let Some(proxy) = &ctx.service.config.networking.media_proxy {
|
|
let params = if is_thumbnail {
|
|
vec![("url", url), ("thumbnail", "1")]
|
|
} else {
|
|
vec![("url", url)]
|
|
};
|
|
|
|
let url = Url::parse_with_params(proxy, ¶ms);
|
|
|
|
if let Err(e) = url {
|
|
warn!("Url parse error: {e}");
|
|
}
|
|
|
|
return url.ok();
|
|
}
|
|
|
|
None
|
|
}
|
|
|
|
pub fn builtin_proxy_file(
|
|
&self,
|
|
ctx: &PackingContext,
|
|
file: &ck::drive_file::Model,
|
|
is_thumbnail: bool,
|
|
) -> Option<Url> {
|
|
let key = if is_thumbnail {
|
|
file.thumbnail_access_key.as_deref()
|
|
} else {
|
|
file.webpublic_access_key.as_deref()
|
|
};
|
|
|
|
if let Some(k) = key {
|
|
if k != "/" {
|
|
let url_raw = format!(
|
|
"{}://{}/files/{}",
|
|
ctx.service.config.networking.protocol.as_ref(),
|
|
&ctx.service.config.networking.host,
|
|
k
|
|
);
|
|
let url = Url::parse(&url_raw);
|
|
|
|
if let Err(e) = url {
|
|
warn!("Url parse error: {e}");
|
|
}
|
|
|
|
return url.ok();
|
|
}
|
|
}
|
|
|
|
None
|
|
}
|
|
|
|
pub fn get_public_url(
|
|
&self,
|
|
ctx: &PackingContext,
|
|
file: &ck::drive_file::Model,
|
|
is_thumbnail: bool,
|
|
) -> Option<Url> {
|
|
if let Some(uri) = &file.uri {
|
|
if file.user_host.is_none() {
|
|
if let Some(media_proxy_url) = self.media_proxy_url(ctx, uri, is_thumbnail) {
|
|
return Some(media_proxy_url);
|
|
}
|
|
|
|
if file.is_link && ctx.service.config.networking.proxy_remote_files {
|
|
if let Some(proxy_url) = self.builtin_proxy_file(ctx, file, is_thumbnail) {
|
|
return Some(proxy_url);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let is_image = matches!(
|
|
file.r#type.as_str(),
|
|
"image/png"
|
|
| "image/apng"
|
|
| "image/gif"
|
|
| "image/jpeg"
|
|
| "image/webp"
|
|
| "image/svg+xml"
|
|
| "image/avif"
|
|
);
|
|
|
|
let url_raw = if is_thumbnail {
|
|
file.thumbnail_url
|
|
.as_deref()
|
|
.or(is_image.then_some(file.webpublic_url.as_deref().unwrap_or(file.url.as_str())))
|
|
} else {
|
|
file.webpublic_url.as_deref().or(Some(file.url.as_str()))
|
|
};
|
|
|
|
if let Some(u) = url_raw {
|
|
let url = Url::parse(u);
|
|
|
|
if let Err(e) = url {
|
|
warn!("Url parse error: {e}");
|
|
}
|
|
|
|
return url.ok();
|
|
}
|
|
|
|
None
|
|
}
|
|
|
|
pub fn pack_existing(
|
|
&self,
|
|
ctx: &PackingContext,
|
|
file: &ck::drive_file::Model,
|
|
) -> PackDriveFileBase {
|
|
let url = self.get_public_url(ctx, file, false);
|
|
let thumbnail_url = self.get_public_url(ctx, file, false);
|
|
|
|
PackDriveFileBase::pack_from((
|
|
Required(Id::from(&file.id)),
|
|
Required(DriveFileBase::extract(
|
|
ctx,
|
|
PackFileBaseInput {
|
|
file: &file,
|
|
effective_url: url.as_ref(),
|
|
effective_thumbnail_url: thumbnail_url.as_ref(),
|
|
},
|
|
)),
|
|
))
|
|
}
|
|
|
|
pub async fn get_cached_base(
|
|
&self,
|
|
ctx: &PackingContext,
|
|
id: &str,
|
|
) -> PackResult<Option<PackDriveFileBase>> {
|
|
let Some(file) = ctx.service.drive_file_cache.get(id).await? else {
|
|
return Ok(None);
|
|
};
|
|
|
|
Ok(Some(self.pack_existing(ctx, file.as_ref())))
|
|
}
|
|
}
|