Fix federated image update duplication for submissions
This commit is contained in:
parent
77abf536f6
commit
f6f603324a
|
@ -405,20 +405,14 @@ pub(super) fn update_note(
|
||||||
return Ok(Err(RecoverableError::MissingImages(missing_files)));
|
return Ok(Err(RecoverableError::MissingImages(missing_files)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut removed_files = vec![];
|
|
||||||
for file in submission.files() {
|
|
||||||
if !existing_files.contains(file) {
|
|
||||||
removed_files.push(*file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Ok(Box::new(UpdateSubmission {
|
Ok(Ok(Box::new(UpdateSubmission {
|
||||||
submission_id,
|
submission_id,
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
published: Some(published.into()),
|
published: Some(published.into()),
|
||||||
removed_files: Some(removed_files),
|
removed_files: None,
|
||||||
new_files: Some(existing_files),
|
new_files: None,
|
||||||
|
only_files: Some(existing_files),
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,6 +260,7 @@ pub struct UpdateSubmission {
|
||||||
published: Option<DateTime<Utc>>,
|
published: Option<DateTime<Utc>>,
|
||||||
removed_files: Option<Vec<Uuid>>,
|
removed_files: Option<Vec<Uuid>>,
|
||||||
new_files: Option<Vec<Uuid>>,
|
new_files: Option<Vec<Uuid>>,
|
||||||
|
only_files: Option<Vec<Uuid>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UpdateSubmission {
|
impl UpdateSubmission {
|
||||||
|
@ -271,6 +272,7 @@ impl UpdateSubmission {
|
||||||
published: None,
|
published: None,
|
||||||
removed_files: None,
|
removed_files: None,
|
||||||
new_files: None,
|
new_files: None,
|
||||||
|
only_files: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,6 +284,7 @@ impl UpdateSubmission {
|
||||||
published: None,
|
published: None,
|
||||||
removed_files: None,
|
removed_files: None,
|
||||||
new_files: Some(vec![file_id]),
|
new_files: Some(vec![file_id]),
|
||||||
|
only_files: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,6 +296,7 @@ impl UpdateSubmission {
|
||||||
published: None,
|
published: None,
|
||||||
removed_files: Some(vec![file_id]),
|
removed_files: Some(vec![file_id]),
|
||||||
new_files: None,
|
new_files: None,
|
||||||
|
only_files: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,6 +308,7 @@ impl UpdateSubmission {
|
||||||
published: Some(Utc::now()),
|
published: Some(Utc::now()),
|
||||||
removed_files: None,
|
removed_files: None,
|
||||||
new_files: None,
|
new_files: None,
|
||||||
|
only_files: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::{
|
||||||
apub::actions::{CreateSubmission, DeleteComment, DeleteSubmission, UpdateSubmission},
|
apub::actions::{CreateSubmission, DeleteComment, DeleteSubmission, UpdateSubmission},
|
||||||
Action, Context, Error, Outbound, Required,
|
Action, Context, Error, Outbound, Required,
|
||||||
};
|
};
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
impl Action for CreateSubmission {
|
impl Action for CreateSubmission {
|
||||||
fn perform(&self, ctx: &Context) -> Result<Option<Box<dyn Outbound + Send>>, Error> {
|
fn perform(&self, ctx: &Context) -> Result<Option<Box<dyn Outbound + Send>>, Error> {
|
||||||
|
@ -98,23 +99,50 @@ impl Action for UpdateSubmission {
|
||||||
}
|
}
|
||||||
let submission = ctx.store.submissions.update(&changes)?;
|
let submission = ctx.store.submissions.update(&changes)?;
|
||||||
|
|
||||||
|
let mut removed_file_ids = HashSet::new();
|
||||||
let mut changes = submission.update_files();
|
let mut changes = submission.update_files();
|
||||||
if let Some(removed) = &self.removed_files {
|
if let Some(files) = &self.only_files {
|
||||||
for file in removed {
|
for file in submission.files() {
|
||||||
if let Ok(Some(file)) = ctx.store.files.by_id(*file) {
|
if let Ok(Some(file)) = ctx.store.files.by_id(*file) {
|
||||||
changes.delete_file(&file);
|
changes.delete_file(&file);
|
||||||
ctx.spawner.purge_file(file.id());
|
removed_file_ids.insert(file.id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if let Some(new) = &self.new_files {
|
for file in files {
|
||||||
for file in new {
|
|
||||||
if let Ok(Some(file)) = ctx.store.files.by_id(*file) {
|
if let Ok(Some(file)) = ctx.store.files.by_id(*file) {
|
||||||
changes.add_file(&file);
|
changes.add_file(&file);
|
||||||
|
removed_file_ids.remove(&file.id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let Some(removed) = &self.removed_files {
|
||||||
|
for file in removed {
|
||||||
|
if let Ok(Some(file)) = ctx.store.files.by_id(*file) {
|
||||||
|
changes.delete_file(&file);
|
||||||
|
removed_file_ids.insert(file.id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(new) = &self.new_files {
|
||||||
|
for file in new {
|
||||||
|
if let Ok(Some(file)) = ctx.store.files.by_id(*file) {
|
||||||
|
changes.add_file(&file);
|
||||||
|
removed_file_ids.remove(&file.id());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.store.submissions.update_files(&changes)?;
|
|
||||||
|
for file_id in removed_file_ids {
|
||||||
|
ctx.spawner.purge_file(file_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let submission = if changes.any_changes() {
|
||||||
|
ctx.store.submissions.update_files(&changes)?
|
||||||
|
} else {
|
||||||
|
submission
|
||||||
|
};
|
||||||
|
|
||||||
let newly_published = !initial_published && submission.published().is_some();
|
let newly_published = !initial_published && submission.published().is_some();
|
||||||
let profile_id = submission.profile_id();
|
let profile_id = submission.profile_id();
|
||||||
|
|
|
@ -415,8 +415,8 @@ impl Submission {
|
||||||
pub fn update_files(&self) -> SubmissionFileChanges {
|
pub fn update_files(&self) -> SubmissionFileChanges {
|
||||||
SubmissionFileChanges {
|
SubmissionFileChanges {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
|
original_files: self.files.clone(),
|
||||||
files: self.files.clone(),
|
files: self.files.clone(),
|
||||||
changed: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -726,25 +726,23 @@ impl SubmissionChanges {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SubmissionFileChanges {
|
pub struct SubmissionFileChanges {
|
||||||
id: Uuid,
|
id: Uuid,
|
||||||
|
original_files: Vec<Uuid>,
|
||||||
files: Vec<Uuid>,
|
files: Vec<Uuid>,
|
||||||
changed: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SubmissionFileChanges {
|
impl SubmissionFileChanges {
|
||||||
pub fn add_file(&mut self, file: &File) -> &mut Self {
|
pub fn add_file(&mut self, file: &File) -> &mut Self {
|
||||||
self.files.push(file.id);
|
self.files.push(file.id);
|
||||||
self.changed = true;
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_file(&mut self, file: &File) -> &mut Self {
|
pub fn delete_file(&mut self, file: &File) -> &mut Self {
|
||||||
self.files.retain(|id| *id != file.id);
|
self.files.retain(|id| *id != file.id);
|
||||||
self.changed = true;
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn any_changes(&self) -> bool {
|
pub(crate) fn any_changes(&self) -> bool {
|
||||||
self.changed
|
self.original_files != self.files
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue