Profiles: combine changes types
This commit is contained in:
parent
2b47dff047
commit
6d58171aa5
|
@ -24,26 +24,15 @@ impl Action for CreateProfile {
|
||||||
if let Some(description) = &self.description {
|
if let Some(description) = &self.description {
|
||||||
changes.description(&hyaenidae_content::html(description));
|
changes.description(&hyaenidae_content::html(description));
|
||||||
}
|
}
|
||||||
let profile = if changes.any_changes() {
|
|
||||||
ctx.store.profiles.update(&changes)?
|
|
||||||
} else {
|
|
||||||
profile
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut changes = profile.update_images();
|
|
||||||
if let Some(banner) = self.banner {
|
if let Some(banner) = self.banner {
|
||||||
if let Ok(Some(file)) = ctx.store.files.by_id(banner) {
|
changes.banner(banner);
|
||||||
changes.banner(&file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if let Some(icon) = self.icon {
|
if let Some(icon) = self.icon {
|
||||||
if let Ok(Some(file)) = ctx.store.files.by_id(icon) {
|
changes.icon(icon);
|
||||||
changes.icon(&file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let profile = if changes.any_changes() {
|
let profile = if changes.any_changes() {
|
||||||
ctx.store.profiles.update_images(&changes)?
|
ctx.store.profiles.update(&changes)?
|
||||||
} else {
|
} else {
|
||||||
profile
|
profile
|
||||||
};
|
};
|
||||||
|
@ -99,38 +88,29 @@ impl Action for UpdateProfile {
|
||||||
if let Some(description_source) = &self.description_source {
|
if let Some(description_source) = &self.description_source {
|
||||||
changes.description_source(description_source);
|
changes.description_source(description_source);
|
||||||
}
|
}
|
||||||
let profile = if changes.any_changes() {
|
|
||||||
ctx.store.profiles.update(&changes)?
|
|
||||||
} else {
|
|
||||||
profile
|
|
||||||
};
|
|
||||||
|
|
||||||
let previous_banner = profile.banner();
|
let previous_banner = profile.banner();
|
||||||
let previous_icon = profile.icon();
|
let previous_icon = profile.icon();
|
||||||
|
|
||||||
let mut changes = profile.update_images();
|
|
||||||
if let Some(banner) = self.banner {
|
if let Some(banner) = self.banner {
|
||||||
if let Ok(Some(file)) = ctx.store.files.by_id(banner) {
|
changes.banner(banner);
|
||||||
changes.banner(&file);
|
if let Some(old_banner) = previous_banner {
|
||||||
if let Some(old_banner) = previous_banner {
|
if old_banner != banner {
|
||||||
if old_banner != banner {
|
ctx.spawner.purge_file(old_banner);
|
||||||
ctx.spawner.purge_file(old_banner);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(icon) = self.icon {
|
if let Some(icon) = self.icon {
|
||||||
if let Ok(Some(file)) = ctx.store.files.by_id(icon) {
|
changes.icon(icon);
|
||||||
changes.icon(&file);
|
if let Some(old_icon) = previous_icon {
|
||||||
if let Some(old_icon) = previous_icon {
|
if old_icon != icon {
|
||||||
if old_icon != icon {
|
ctx.spawner.purge_file(old_icon);
|
||||||
ctx.spawner.purge_file(old_icon);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let profile = if changes.any_changes() {
|
let profile = if changes.any_changes() {
|
||||||
ctx.store.profiles.update_images(&changes)?
|
ctx.store.profiles.update(&changes)?
|
||||||
} else {
|
} else {
|
||||||
profile
|
profile
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,20 +28,14 @@ impl Action for CreateSubmission {
|
||||||
changes.description(&hyaenidae_content::html(description));
|
changes.description(&hyaenidae_content::html(description));
|
||||||
}
|
}
|
||||||
|
|
||||||
let submission = if changes.any_changes() {
|
|
||||||
ctx.store.submissions.update(&changes)?
|
|
||||||
} else {
|
|
||||||
submission
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut changes = submission.update_files();
|
|
||||||
for file in &self.files {
|
for file in &self.files {
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let submission = if changes.any_changes() {
|
let submission = if changes.any_changes() {
|
||||||
ctx.store.submissions.update_files(&changes)?
|
ctx.store.submissions.update(&changes)?
|
||||||
} else {
|
} else {
|
||||||
submission
|
submission
|
||||||
};
|
};
|
||||||
|
@ -131,14 +125,8 @@ impl Action for UpdateSubmission {
|
||||||
if let Some(sensitive) = self.sensitive {
|
if let Some(sensitive) = self.sensitive {
|
||||||
changes.sensitive(sensitive);
|
changes.sensitive(sensitive);
|
||||||
}
|
}
|
||||||
let submission = if changes.any_changes() {
|
|
||||||
ctx.store.submissions.update(&changes)?
|
|
||||||
} else {
|
|
||||||
submission
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut removed_file_ids = HashSet::new();
|
let mut removed_file_ids = HashSet::new();
|
||||||
let mut changes = submission.update_files();
|
|
||||||
if let Some(files) = &self.only_files {
|
if let Some(files) = &self.only_files {
|
||||||
for file in submission.files() {
|
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) {
|
||||||
|
@ -177,7 +165,7 @@ impl Action for UpdateSubmission {
|
||||||
}
|
}
|
||||||
|
|
||||||
let submission = if changes.any_changes() {
|
let submission = if changes.any_changes() {
|
||||||
ctx.store.submissions.update_files(&changes)?
|
ctx.store.submissions.update(&changes)?
|
||||||
} else {
|
} else {
|
||||||
submission
|
submission
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,13 +15,11 @@ pub mod view;
|
||||||
|
|
||||||
pub use comment::Store as CommentStore;
|
pub use comment::Store as CommentStore;
|
||||||
pub use file::Store as FileStore;
|
pub use file::Store as FileStore;
|
||||||
pub use profile::Store as ProfileStore;
|
pub use profile::{OwnerSource, Profile, ProfileChanges, Store as ProfileStore};
|
||||||
pub use react::Store as ReactStore;
|
pub use react::Store as ReactStore;
|
||||||
pub use report::Store as ReportStore;
|
pub use report::Store as ReportStore;
|
||||||
pub use server::{Server, ServerChanges, Store as ServerStore};
|
pub use server::{Server, ServerChanges, Store as ServerStore};
|
||||||
pub use submission::{
|
pub use submission::{Store as SubmissionStore, Submission, SubmissionChanges, Visibility};
|
||||||
Store as SubmissionStore, Submission, SubmissionChanges, SubmissionFileChanges, Visibility,
|
|
||||||
};
|
|
||||||
pub use term_search::TermSearch;
|
pub use term_search::TermSearch;
|
||||||
pub use view::Store as ViewStore;
|
pub use view::Store as ViewStore;
|
||||||
|
|
||||||
|
@ -222,115 +220,6 @@ enum ReportState {
|
||||||
Resolved,
|
Resolved,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum OwnerSource {
|
|
||||||
Local(Uuid),
|
|
||||||
Remote(Uuid),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OwnerSource {
|
|
||||||
pub fn is_local(&self) -> bool {
|
|
||||||
matches!(self, OwnerSource::Local(_))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct Profile {
|
|
||||||
id: Uuid,
|
|
||||||
owner_source: OwnerSource,
|
|
||||||
handle: String,
|
|
||||||
domain: String,
|
|
||||||
display_name: Option<String>,
|
|
||||||
display_name_source: Option<String>,
|
|
||||||
description: Option<String>,
|
|
||||||
description_source: Option<String>,
|
|
||||||
icon: Option<Uuid>,
|
|
||||||
banner: Option<Uuid>,
|
|
||||||
published: DateTime<Utc>,
|
|
||||||
login_required: bool,
|
|
||||||
suspended: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Profile {
|
|
||||||
pub fn update(&self) -> ProfileChanges {
|
|
||||||
ProfileChanges {
|
|
||||||
id: self.id,
|
|
||||||
display_name: None,
|
|
||||||
display_name_source: None,
|
|
||||||
description: None,
|
|
||||||
description_source: None,
|
|
||||||
login_required: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_images(&self) -> ProfileImageChanges {
|
|
||||||
ProfileImageChanges {
|
|
||||||
id: self.id,
|
|
||||||
icon: None,
|
|
||||||
banner: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn id(&self) -> Uuid {
|
|
||||||
self.id
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn owner_source(&self) -> &OwnerSource {
|
|
||||||
&self.owner_source
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn local_owner(&self) -> Option<Uuid> {
|
|
||||||
match self.owner_source {
|
|
||||||
OwnerSource::Local(id) => Some(id),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle(&self) -> &str {
|
|
||||||
&self.handle
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn domain(&self) -> &str {
|
|
||||||
&self.domain
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn display_name(&self) -> Option<&str> {
|
|
||||||
self.display_name.as_deref()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn display_name_source(&self) -> Option<&str> {
|
|
||||||
self.display_name_source.as_deref()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn description(&self) -> Option<&str> {
|
|
||||||
self.description.as_ref().map(|d| d.as_str())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn description_source(&self) -> Option<&str> {
|
|
||||||
self.description_source.as_deref()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn icon(&self) -> Option<Uuid> {
|
|
||||||
self.icon
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn banner(&self) -> Option<Uuid> {
|
|
||||||
self.banner
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn published(&self) -> DateTime<Utc> {
|
|
||||||
self.published
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn login_required(&self) -> bool {
|
|
||||||
self.login_required
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_suspended(&self) -> bool {
|
|
||||||
self.suspended
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PictRsFile {
|
pub struct PictRsFile {
|
||||||
key: String,
|
key: String,
|
||||||
|
@ -590,70 +479,6 @@ pub struct ReplyReact {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Undo<T>(pub T);
|
pub struct Undo<T>(pub T);
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ProfileChanges {
|
|
||||||
id: Uuid,
|
|
||||||
display_name: Option<String>,
|
|
||||||
display_name_source: Option<String>,
|
|
||||||
description: Option<String>,
|
|
||||||
description_source: Option<String>,
|
|
||||||
login_required: Option<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ProfileChanges {
|
|
||||||
pub(crate) fn display_name(&mut self, display_name: &str) -> &mut Self {
|
|
||||||
self.display_name = Some(display_name.to_owned());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn display_name_source(&mut self, display_name_source: &str) -> &mut Self {
|
|
||||||
self.display_name_source = Some(display_name_source.to_owned());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn description(&mut self, description: &str) -> &mut Self {
|
|
||||||
self.description = Some(description.to_owned());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn description_source(&mut self, description_source: &str) -> &mut Self {
|
|
||||||
self.description_source = Some(description_source.to_owned());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn login_required(&mut self, required: bool) -> &mut Self {
|
|
||||||
self.login_required = Some(required);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn any_changes(&self) -> bool {
|
|
||||||
self.display_name.is_some() || self.description.is_some() || self.login_required.is_some()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ProfileImageChanges {
|
|
||||||
id: Uuid,
|
|
||||||
icon: Option<Uuid>,
|
|
||||||
banner: Option<Uuid>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ProfileImageChanges {
|
|
||||||
pub(crate) fn icon(&mut self, file: &File) -> &mut Self {
|
|
||||||
self.icon = Some(file.id);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn banner(&mut self, file: &File) -> &mut Self {
|
|
||||||
self.banner = Some(file.id);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn any_changes(&self) -> bool {
|
|
||||||
self.icon.is_some() || self.banner.is_some()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CommentChanges {
|
pub struct CommentChanges {
|
||||||
id: Uuid,
|
id: Uuid,
|
||||||
|
|
|
@ -1,11 +1,43 @@
|
||||||
use super::{
|
use super::{StoreError, TermSearch, Undo};
|
||||||
OwnerSource, Profile, ProfileChanges, ProfileImageChanges, StoreError, TermSearch, Undo,
|
|
||||||
};
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use sled::{Db, Transactional, Tree};
|
use sled::{Db, Transactional, Tree};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ProfileChanges {
|
||||||
|
id: Uuid,
|
||||||
|
display_name: Option<String>,
|
||||||
|
display_name_source: Option<String>,
|
||||||
|
description: Option<String>,
|
||||||
|
description_source: Option<String>,
|
||||||
|
login_required: Option<bool>,
|
||||||
|
icon: Option<Uuid>,
|
||||||
|
banner: Option<Uuid>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum OwnerSource {
|
||||||
|
Local(Uuid),
|
||||||
|
Remote(Uuid),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Profile {
|
||||||
|
id: Uuid,
|
||||||
|
owner_source: OwnerSource,
|
||||||
|
handle: String,
|
||||||
|
domain: String,
|
||||||
|
display_name: Option<String>,
|
||||||
|
display_name_source: Option<String>,
|
||||||
|
description: Option<String>,
|
||||||
|
description_source: Option<String>,
|
||||||
|
icon: Option<Uuid>,
|
||||||
|
banner: Option<Uuid>,
|
||||||
|
published: DateTime<Utc>,
|
||||||
|
login_required: bool,
|
||||||
|
suspended: bool,
|
||||||
|
}
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Store {
|
pub struct Store {
|
||||||
profile_tree: Tree,
|
profile_tree: Tree,
|
||||||
|
@ -48,6 +80,131 @@ struct StoredProfile {
|
||||||
suspended_at: Option<DateTime<Utc>>,
|
suspended_at: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ProfileChanges {
|
||||||
|
pub(crate) fn display_name(&mut self, display_name: &str) -> &mut Self {
|
||||||
|
self.display_name = Some(display_name.to_owned());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn display_name_source(&mut self, display_name_source: &str) -> &mut Self {
|
||||||
|
self.display_name_source = Some(display_name_source.to_owned());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn description(&mut self, description: &str) -> &mut Self {
|
||||||
|
self.description = Some(description.to_owned());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn description_source(&mut self, description_source: &str) -> &mut Self {
|
||||||
|
self.description_source = Some(description_source.to_owned());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn login_required(&mut self, required: bool) -> &mut Self {
|
||||||
|
self.login_required = Some(required);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn icon(&mut self, file_id: Uuid) -> &mut Self {
|
||||||
|
self.icon = Some(file_id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn banner(&mut self, file_id: Uuid) -> &mut Self {
|
||||||
|
self.banner = Some(file_id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn any_changes(&self) -> bool {
|
||||||
|
self.display_name.is_some()
|
||||||
|
|| self.description.is_some()
|
||||||
|
|| self.login_required.is_some()
|
||||||
|
|| self.icon.is_some()
|
||||||
|
|| self.banner.is_some()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OwnerSource {
|
||||||
|
pub fn is_local(&self) -> bool {
|
||||||
|
matches!(self, OwnerSource::Local(_))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Profile {
|
||||||
|
pub fn update(&self) -> ProfileChanges {
|
||||||
|
ProfileChanges {
|
||||||
|
id: self.id,
|
||||||
|
display_name: None,
|
||||||
|
display_name_source: None,
|
||||||
|
description: None,
|
||||||
|
description_source: None,
|
||||||
|
login_required: None,
|
||||||
|
icon: None,
|
||||||
|
banner: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn id(&self) -> Uuid {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn owner_source(&self) -> &OwnerSource {
|
||||||
|
&self.owner_source
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn local_owner(&self) -> Option<Uuid> {
|
||||||
|
match self.owner_source {
|
||||||
|
OwnerSource::Local(id) => Some(id),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle(&self) -> &str {
|
||||||
|
&self.handle
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn domain(&self) -> &str {
|
||||||
|
&self.domain
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn display_name(&self) -> Option<&str> {
|
||||||
|
self.display_name.as_deref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn display_name_source(&self) -> Option<&str> {
|
||||||
|
self.display_name_source.as_deref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn description(&self) -> Option<&str> {
|
||||||
|
self.description.as_ref().map(|d| d.as_str())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn description_source(&self) -> Option<&str> {
|
||||||
|
self.description_source.as_deref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon(&self) -> Option<Uuid> {
|
||||||
|
self.icon
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn banner(&self) -> Option<Uuid> {
|
||||||
|
self.banner
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn published(&self) -> DateTime<Utc> {
|
||||||
|
self.published
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn login_required(&self) -> bool {
|
||||||
|
self.login_required
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_suspended(&self) -> bool {
|
||||||
|
self.suspended
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Store {
|
impl Store {
|
||||||
pub(super) fn build(db: &Db) -> Result<Self, sled::Error> {
|
pub(super) fn build(db: &Db) -> Result<Self, sled::Error> {
|
||||||
Ok(Store {
|
Ok(Store {
|
||||||
|
@ -223,43 +380,10 @@ impl Store {
|
||||||
if let Some(description_source) = &profile_changes.description_source {
|
if let Some(description_source) = &profile_changes.description_source {
|
||||||
stored_profile.description_source = Some(description_source.clone());
|
stored_profile.description_source = Some(description_source.clone());
|
||||||
}
|
}
|
||||||
stored_profile.updated_at = Utc::now().into();
|
if let Some(icon) = profile_changes.icon {
|
||||||
|
|
||||||
let stored_profile_vec = serde_json::to_vec(&stored_profile)?;
|
|
||||||
|
|
||||||
if self
|
|
||||||
.profile_tree
|
|
||||||
.compare_and_swap(
|
|
||||||
id_profile_key(profile_changes.id).as_bytes(),
|
|
||||||
Some(&stored_profile_ivec),
|
|
||||||
Some(stored_profile_vec),
|
|
||||||
)?
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
return Err(StoreError::DoubleStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(stored_profile.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn update_images(
|
|
||||||
&self,
|
|
||||||
profile_image_changes: &ProfileImageChanges,
|
|
||||||
) -> Result<Profile, StoreError> {
|
|
||||||
let stored_profile_ivec = match self
|
|
||||||
.profile_tree
|
|
||||||
.get(id_profile_key(profile_image_changes.id).as_bytes())?
|
|
||||||
{
|
|
||||||
Some(ivec) => ivec,
|
|
||||||
None => return Err(StoreError::Missing),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut stored_profile: StoredProfile = serde_json::from_slice(&stored_profile_ivec)?;
|
|
||||||
|
|
||||||
if let Some(icon) = profile_image_changes.icon {
|
|
||||||
stored_profile.icon = Some(icon);
|
stored_profile.icon = Some(icon);
|
||||||
}
|
}
|
||||||
if let Some(banner) = profile_image_changes.banner {
|
if let Some(banner) = profile_changes.banner {
|
||||||
stored_profile.banner = Some(banner);
|
stored_profile.banner = Some(banner);
|
||||||
}
|
}
|
||||||
stored_profile.updated_at = Utc::now().into();
|
stored_profile.updated_at = Utc::now().into();
|
||||||
|
@ -269,7 +393,7 @@ impl Store {
|
||||||
if self
|
if self
|
||||||
.profile_tree
|
.profile_tree
|
||||||
.compare_and_swap(
|
.compare_and_swap(
|
||||||
id_profile_key(profile_image_changes.id).as_bytes(),
|
id_profile_key(profile_changes.id).as_bytes(),
|
||||||
Some(&stored_profile_ivec),
|
Some(&stored_profile_ivec),
|
||||||
Some(stored_profile_vec),
|
Some(stored_profile_vec),
|
||||||
)?
|
)?
|
||||||
|
|
|
@ -41,11 +41,6 @@ pub struct SubmissionChanges {
|
||||||
local_only: Option<bool>,
|
local_only: Option<bool>,
|
||||||
logged_in_only: Option<bool>,
|
logged_in_only: Option<bool>,
|
||||||
sensitive: Option<bool>,
|
sensitive: Option<bool>,
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct SubmissionFileChanges {
|
|
||||||
id: Uuid,
|
|
||||||
original_files: Vec<Uuid>,
|
original_files: Vec<Uuid>,
|
||||||
files: Vec<Uuid>,
|
files: Vec<Uuid>,
|
||||||
}
|
}
|
||||||
|
@ -100,12 +95,6 @@ impl Submission {
|
||||||
local_only: None,
|
local_only: None,
|
||||||
logged_in_only: None,
|
logged_in_only: None,
|
||||||
sensitive: None,
|
sensitive: None,
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_files(&self) -> SubmissionFileChanges {
|
|
||||||
SubmissionFileChanges {
|
|
||||||
id: self.id,
|
|
||||||
original_files: self.files.clone(),
|
original_files: self.files.clone(),
|
||||||
files: self.files.clone(),
|
files: self.files.clone(),
|
||||||
}
|
}
|
||||||
|
@ -237,19 +226,6 @@ impl SubmissionChanges {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn any_changes(&self) -> bool {
|
|
||||||
self.title.is_some()
|
|
||||||
|| self.description.is_some()
|
|
||||||
|| self.published.is_some()
|
|
||||||
|| self.updated.is_some()
|
|
||||||
|| self.visibility.is_some()
|
|
||||||
|| self.local_only.is_some()
|
|
||||||
|| self.logged_in_only.is_some()
|
|
||||||
|| self.sensitive.is_some()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SubmissionFileChanges {
|
|
||||||
pub(crate) fn add_file(&mut self, file: &File) -> &mut Self {
|
pub(crate) fn add_file(&mut self, file: &File) -> &mut Self {
|
||||||
self.files.push(file.id);
|
self.files.push(file.id);
|
||||||
self
|
self
|
||||||
|
@ -261,7 +237,15 @@ impl SubmissionFileChanges {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn any_changes(&self) -> bool {
|
pub(crate) fn any_changes(&self) -> bool {
|
||||||
self.original_files != self.files
|
self.title.is_some()
|
||||||
|
|| self.description.is_some()
|
||||||
|
|| self.published.is_some()
|
||||||
|
|| self.updated.is_some()
|
||||||
|
|| self.visibility.is_some()
|
||||||
|
|| self.local_only.is_some()
|
||||||
|
|| self.logged_in_only.is_some()
|
||||||
|
|| self.sensitive.is_some()
|
||||||
|
|| self.original_files != self.files
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,6 +405,7 @@ impl Store {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stored_submission.published = changes.published;
|
stored_submission.published = changes.published;
|
||||||
|
stored_submission.files = changes.files.clone();
|
||||||
|
|
||||||
let stored_submission_vec = serde_json::to_vec(&stored_submission)?;
|
let stored_submission_vec = serde_json::to_vec(&stored_submission)?;
|
||||||
|
|
||||||
|
@ -463,35 +448,6 @@ impl Store {
|
||||||
Ok(stored_submission.into())
|
Ok(stored_submission.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_files(&self, changes: &SubmissionFileChanges) -> Result<Submission, StoreError> {
|
|
||||||
let stored_submission_ivec =
|
|
||||||
match self.submission_tree.get(id_submission_key(changes.id))? {
|
|
||||||
Some(ivec) => ivec,
|
|
||||||
None => return Err(StoreError::Missing),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut stored_submission: StoredSubmission =
|
|
||||||
serde_json::from_slice(&stored_submission_ivec)?;
|
|
||||||
|
|
||||||
stored_submission.files = changes.files.clone();
|
|
||||||
|
|
||||||
let stored_submission_vec = serde_json::to_vec(&stored_submission)?;
|
|
||||||
|
|
||||||
if self
|
|
||||||
.submission_tree
|
|
||||||
.compare_and_swap(
|
|
||||||
id_submission_key(changes.id),
|
|
||||||
Some(&stored_submission_ivec),
|
|
||||||
Some(stored_submission_vec.as_slice()),
|
|
||||||
)?
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
return Err(StoreError::DoubleStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(stored_submission.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract<T, F>(&self, submission_id: Uuid, f: F) -> Option<T>
|
fn extract<T, F>(&self, submission_id: Uuid, f: F) -> Option<T>
|
||||||
where
|
where
|
||||||
F: FnOnce(StoredSubmission) -> Option<T>,
|
F: FnOnce(StoredSubmission) -> Option<T>,
|
||||||
|
|
Loading…
Reference in a new issue