104 lines
3.3 KiB
Rust
104 lines
3.3 KiB
Rust
use crate::model::data::user::UserBaseSource;
|
|
use crate::model::processing::drive::DriveModel;
|
|
use crate::model::processing::emoji::EmojiModel;
|
|
use crate::model::processing::{get_mm_token_emoji, PackResult};
|
|
use crate::model::{PackType, PackingContext};
|
|
use magnetar_calckey_model::ck;
|
|
use magnetar_sdk::mmm::Token;
|
|
use magnetar_sdk::types::drive::PackDriveFileBase;
|
|
use magnetar_sdk::types::emoji::EmojiContext;
|
|
use magnetar_sdk::types::instance::InstanceTicker;
|
|
use magnetar_sdk::types::user::{PackUserBase, UserBase};
|
|
use magnetar_sdk::types::{Id, MmXml};
|
|
use magnetar_sdk::{mmm, Packed, Required};
|
|
use tracing::warn;
|
|
use url::Url;
|
|
|
|
pub struct UserModel;
|
|
|
|
impl UserModel {
|
|
pub fn tokenize_username(&self, user: &ck::user::Model) -> Token {
|
|
mmm::Context::default().parse_ui(user.name.as_deref().unwrap_or(&user.username))
|
|
}
|
|
|
|
pub fn get_effective_avatar_url(
|
|
&self,
|
|
ctx: &PackingContext,
|
|
user: &ck::user::Model,
|
|
avatar: Option<&PackDriveFileBase>,
|
|
) -> PackResult<Url> {
|
|
Ok(avatar
|
|
.and_then(
|
|
|PackDriveFileBase {
|
|
file: Required(base),
|
|
..
|
|
}| base.thumbnail_url.as_deref(),
|
|
)
|
|
.map(Url::parse)
|
|
.and_then(|r| {
|
|
if let Err(e) = r {
|
|
warn!("Failed to parse avatar URL: {e}");
|
|
}
|
|
|
|
r.ok().map(Ok)
|
|
})
|
|
.unwrap_or_else(|| {
|
|
Url::parse(&format!(
|
|
"{}://{}/identicon/{}",
|
|
ctx.service.config.networking.protocol,
|
|
ctx.service.config.networking.host,
|
|
user.id
|
|
))
|
|
})?)
|
|
}
|
|
|
|
pub async fn base_from_existing(
|
|
&self,
|
|
ctx: &PackingContext,
|
|
user: &ck::user::Model,
|
|
) -> PackResult<PackUserBase> {
|
|
let drive_file_pack = DriveModel;
|
|
let avatar = match &user.avatar_id {
|
|
Some(av_id) => drive_file_pack.get_cached_base(ctx, av_id).await?,
|
|
None => None,
|
|
};
|
|
let avatar_url = &self.get_effective_avatar_url(ctx, user, avatar.as_ref())?;
|
|
|
|
let username_mm = self.tokenize_username(&user);
|
|
|
|
let emoji_model = EmojiModel;
|
|
let shortcodes = emoji_model.deduplicate_emoji(ctx, get_mm_token_emoji(&username_mm));
|
|
let emojis = emoji_model
|
|
.fetch_many_emojis(ctx, &shortcodes, user.host.as_deref())
|
|
.await?;
|
|
let instance = ctx
|
|
.service
|
|
.remote_instance_cache
|
|
.get(
|
|
user.host
|
|
.as_deref()
|
|
.unwrap_or(&ctx.service.config.networking.host),
|
|
)
|
|
.await?
|
|
.map(|i| InstanceTicker::extract(ctx, i.as_ref()));
|
|
let emoji_context = EmojiContext(emojis);
|
|
|
|
let base = UserBase::extract(
|
|
ctx,
|
|
UserBaseSource {
|
|
user,
|
|
username_mm: mmm::to_xml_string(&username_mm).map(MmXml).as_ref().ok(),
|
|
avatar_url,
|
|
avatar: avatar.as_ref(),
|
|
emoji_context: &emoji_context,
|
|
instance: instance.as_ref(),
|
|
},
|
|
);
|
|
|
|
Ok(PackUserBase::pack_from((
|
|
Required(Id::from(&user.id)),
|
|
Required(base),
|
|
)))
|
|
}
|
|
}
|