use crate::{ apub::actions::{CreateProfile, DeleteProfile, DeleteSubmission, UpdateProfile}, Action, Context, Error, Required, }; impl Action for CreateProfile { fn perform(&self, context: &Context) -> Result<(), Error> { let profile = context.store.profiles.create( self.owner_source.clone(), &self.handle, &self.domain, self.published, )?; let mut changes = profile.update(); changes.login_required(self.login_required); if let Some(display_name) = &self.display_name { changes.display_name(display_name); } if let Some(description) = &self.description { changes.description(description); } let profile = context.store.profiles.update(&changes)?; let mut changes = profile.update_images(); if let Some(banner) = self.banner { if let Ok(Some(file)) = context.store.files.by_id(banner) { changes.banner(&file); } } if let Some(icon) = self.icon { if let Ok(Some(file)) = context.store.files.by_id(icon) { changes.banner(&file); } } let profile = context.store.profiles.update_images(&changes)?; context .apub .store_public_key(profile.id(), &self.public_key_id, &self.public_key)?; context.apub.profile(&self.apub_id, profile.id())?; Ok(()) } } impl Action for UpdateProfile { fn perform(&self, context: &Context) -> Result<(), Error> { let profile = context.store.profiles.by_id(self.profile_id)?.req()?; let mut changes = profile.update(); changes.login_required(self.login_required); if let Some(display_name) = &self.display_name { changes.display_name(display_name); } if let Some(description) = &self.description { changes.description(description); } let profile = context.store.profiles.update(&changes)?; let mut changes = profile.update_images(); if let Some(banner) = self.banner { if let Ok(Some(file)) = context.store.files.by_id(banner) { changes.banner(&file); } } if let Some(icon) = self.icon { if let Ok(Some(file)) = context.store.files.by_id(icon) { changes.banner(&file); } } let profile = context.store.profiles.update_images(&changes)?; context .apub .store_public_key(profile.id(), &self.public_key_id, &self.public_key)?; Ok(()) } } impl Action for DeleteProfile { fn perform(&self, context: &Context) -> Result<(), Error> { let opt = context.store.profiles.delete(self.profile_id)?; if let Some(undo_profile) = opt { if let Some(banner) = undo_profile.0.banner() { context.spawner.purge_file(banner); } if let Some(icon) = undo_profile.0.icon() { context.spawner.purge_file(icon); } let profile_id = self.profile_id; let context_clone = context.clone(); context.arbiter.send(Box::pin(async move { let _ = actix_web::web::block(move || { for submission_id in context_clone.store.submissions.for_profile(profile_id) { if let Err(e) = Action::perform(&DeleteSubmission { submission_id }, &context_clone) { log::error!("Failed to delete submission {}: {}", submission_id, e); } } Ok(()) as Result<(), ()> }) .await; })); } Ok(()) } }