2021-01-04 17:34:31 +00:00
|
|
|
use crate::{
|
2021-01-04 17:41:34 +00:00
|
|
|
apub::actions::{
|
2021-01-04 17:34:31 +00:00
|
|
|
AnnounceSubmission, CreateSubmission, DeleteComment, DeleteSubmission, UpdateSubmission,
|
|
|
|
},
|
|
|
|
Action, Context, Error, Required,
|
|
|
|
};
|
|
|
|
use std::collections::HashSet;
|
|
|
|
|
|
|
|
impl Action for CreateSubmission {
|
|
|
|
fn perform(&self, context: &Context) -> Result<(), Error> {
|
|
|
|
let submission =
|
|
|
|
context
|
|
|
|
.store
|
|
|
|
.submissions
|
|
|
|
.create(self.profile_id, &self.title, self.visibility)?;
|
|
|
|
|
|
|
|
let mut changes = submission.update();
|
|
|
|
changes.publish(Some(self.published));
|
|
|
|
if let Some(description) = &self.description {
|
|
|
|
changes.description(description);
|
|
|
|
}
|
|
|
|
let submission = context.store.submissions.update(&changes)?;
|
|
|
|
let mut changes = submission.update_files();
|
|
|
|
for file in &self.files {
|
|
|
|
if let Ok(Some(file)) = context.store.files.by_id(*file) {
|
|
|
|
changes.add_file(&file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let submission = context.store.submissions.update_files(&changes)?;
|
|
|
|
|
|
|
|
context.apub.submission(&self.apub_id, submission.id())?;
|
|
|
|
|
|
|
|
let submission_id = submission.id();
|
|
|
|
let profile_id = self.profile_id;
|
|
|
|
let published = submission.published().req()?;
|
|
|
|
let context_clone = context.clone();
|
|
|
|
context.arbiter.send(Box::pin(async move {
|
|
|
|
let _ = actix_web::web::block(move || {
|
|
|
|
for follower_id in context_clone.store.view.follows.forward_iter(profile_id) {
|
|
|
|
if let Ok(Some(true)) = context_clone.store.profiles.is_local(follower_id) {
|
|
|
|
context_clone.store.view.submissions.new(
|
|
|
|
follower_id,
|
|
|
|
submission_id,
|
|
|
|
published,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(()) as Result<(), ()>
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}));
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Action for AnnounceSubmission {
|
|
|
|
fn perform(&self, _: &Context) -> Result<(), Error> {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Action for UpdateSubmission {
|
|
|
|
fn perform(&self, context: &Context) -> Result<(), Error> {
|
|
|
|
let submission = context.store.submissions.by_id(self.submission_id)?.req()?;
|
|
|
|
|
|
|
|
let mut changes = submission.update();
|
|
|
|
if let Some(title) = &self.title {
|
|
|
|
changes.title(title);
|
|
|
|
}
|
|
|
|
if let Some(description) = &self.description {
|
|
|
|
changes.description(description);
|
|
|
|
}
|
|
|
|
let submission = context.store.submissions.update(&changes)?;
|
|
|
|
|
|
|
|
let mut original_files = submission.files().iter().cloned().collect::<HashSet<_>>();
|
|
|
|
let mut changes = submission.update_files();
|
|
|
|
for file in &self.files {
|
|
|
|
original_files.remove(file);
|
|
|
|
if let Ok(Some(file)) = context.store.files.by_id(*file) {
|
|
|
|
changes.add_file(&file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
context.store.submissions.update_files(&changes)?;
|
|
|
|
for file in original_files {
|
|
|
|
context.spawner.purge_file(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Action for DeleteSubmission {
|
|
|
|
fn perform(&self, context: &Context) -> Result<(), Error> {
|
|
|
|
let opt = context.store.submissions.delete(self.submission_id)?;
|
|
|
|
|
|
|
|
if let Some(undo_submission) = opt {
|
|
|
|
for comment_id in context.store.comments.for_submission(self.submission_id) {
|
|
|
|
if let Err(e) = Action::perform(&DeleteComment { comment_id }, context) {
|
|
|
|
log::error!("Failed to delete comment {}: {}", comment_id, e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for file_id in undo_submission.0.files() {
|
|
|
|
context.spawner.purge_file(*file_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
let submission_id = self.submission_id;
|
|
|
|
let context_clone = context.clone();
|
|
|
|
context.arbiter.send(Box::pin(async move {
|
|
|
|
let _ = actix_web::web::block(move || {
|
|
|
|
context_clone.store.view.submissions.remove(submission_id);
|
|
|
|
Ok(()) as Result<(), ()>
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|