Misc v3 linear tasks (#767)

* v3_reroute 404 error

* hash change

* fixed issue with error conversion

* added new model confirmation tests
+ title name change

* renaming, fields

* owner; test changes

* clippy prepare

* fmt

* merge fixes

* clippy

* working merge

* revs

* merge fixes
This commit is contained in:
Wyatt Verchere
2023-12-01 19:15:00 -08:00
committed by GitHub
parent 2d92b08404
commit a70df067bc
119 changed files with 2897 additions and 1334 deletions

View File

@@ -1,3 +1,5 @@
// Legacy models from V2, where its useful to keep the struct for rerouting/conversion
pub mod notifications;
pub mod projects;
pub mod search;
pub mod teams;

View File

@@ -0,0 +1,183 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::models::{
ids::{
NotificationId, OrganizationId, ProjectId, ReportId, TeamId, ThreadId, ThreadMessageId,
UserId, VersionId,
},
notifications::{Notification, NotificationAction, NotificationBody},
projects::ProjectStatus,
};
#[derive(Serialize, Deserialize)]
pub struct LegacyNotification {
pub id: NotificationId,
pub user_id: UserId,
pub read: bool,
pub created: DateTime<Utc>,
pub body: LegacyNotificationBody,
// DEPRECATED: use body field instead
#[serde(rename = "type")]
pub type_: Option<String>,
pub title: String,
pub text: String,
pub link: String,
pub actions: Vec<LegacyNotificationAction>,
}
#[derive(Serialize, Deserialize, Clone)]
pub struct LegacyNotificationAction {
pub title: String,
/// The route to call when this notification action is called. Formatted HTTP Method, route
pub action_route: (String, String),
}
#[derive(Serialize, Deserialize)]
pub enum LegacyNotificationBody {
ProjectUpdate {
project_id: ProjectId,
version_id: VersionId,
},
TeamInvite {
project_id: ProjectId,
team_id: TeamId,
invited_by: UserId,
role: String,
},
OrganizationInvite {
organization_id: OrganizationId,
invited_by: UserId,
team_id: TeamId,
role: String,
},
StatusChange {
project_id: ProjectId,
old_status: ProjectStatus,
new_status: ProjectStatus,
},
ModeratorMessage {
thread_id: ThreadId,
message_id: ThreadMessageId,
project_id: Option<ProjectId>,
report_id: Option<ReportId>,
},
LegacyMarkdown {
notification_type: Option<String>,
title: String,
text: String,
link: String,
actions: Vec<NotificationAction>,
},
Unknown,
}
impl LegacyNotification {
pub fn from(notification: Notification) -> Self {
let type_ = match &notification.body {
NotificationBody::ProjectUpdate { .. } => Some("project_update".to_string()),
NotificationBody::TeamInvite { .. } => Some("team_invite".to_string()),
NotificationBody::OrganizationInvite { .. } => Some("organization_invite".to_string()),
NotificationBody::StatusChange { .. } => Some("status_change".to_string()),
NotificationBody::ModeratorMessage { .. } => Some("moderator_message".to_string()),
NotificationBody::LegacyMarkdown {
notification_type, ..
} => notification_type.clone(),
NotificationBody::Unknown => None,
};
let legacy_body = match notification.body {
NotificationBody::ProjectUpdate {
project_id,
version_id,
} => LegacyNotificationBody::ProjectUpdate {
project_id,
version_id,
},
NotificationBody::TeamInvite {
project_id,
team_id,
invited_by,
role,
} => LegacyNotificationBody::TeamInvite {
project_id,
team_id,
invited_by,
role,
},
NotificationBody::OrganizationInvite {
organization_id,
invited_by,
team_id,
role,
} => LegacyNotificationBody::OrganizationInvite {
organization_id,
invited_by,
team_id,
role,
},
NotificationBody::StatusChange {
project_id,
old_status,
new_status,
} => LegacyNotificationBody::StatusChange {
project_id,
old_status,
new_status,
},
NotificationBody::ModeratorMessage {
thread_id,
message_id,
project_id,
report_id,
} => LegacyNotificationBody::ModeratorMessage {
thread_id,
message_id,
project_id,
report_id,
},
NotificationBody::LegacyMarkdown {
notification_type,
name,
text,
link,
actions,
} => LegacyNotificationBody::LegacyMarkdown {
notification_type,
title: name,
text,
link,
actions,
},
NotificationBody::Unknown => LegacyNotificationBody::Unknown,
};
Self {
id: notification.id,
user_id: notification.user_id,
read: notification.read,
created: notification.created,
body: legacy_body,
type_,
title: notification.name,
text: notification.text,
link: notification.link,
actions: notification
.actions
.into_iter()
.map(LegacyNotificationAction::from)
.collect(),
}
}
}
impl LegacyNotificationAction {
pub fn from(notification_action: NotificationAction) -> Self {
Self {
title: notification_action.name,
action_route: notification_action.action_route,
}
}
}

View File

@@ -10,7 +10,7 @@ use crate::database::models::{version_item, DatabaseError};
use crate::database::redis::RedisPool;
use crate::models::ids::{ProjectId, VersionId};
use crate::models::projects::{
Dependency, GalleryItem, License, Link, Loader, ModeratorMessage, MonetizationStatus, Project,
Dependency, License, Link, Loader, ModeratorMessage, MonetizationStatus, Project,
ProjectStatus, Version, VersionFile, VersionStatus, VersionType,
};
use crate::models::threads::ThreadId;
@@ -63,7 +63,7 @@ pub struct LegacyProject {
pub wiki_url: Option<String>,
pub discord_url: Option<String>,
pub donation_urls: Option<Vec<DonationLink>>,
pub gallery: Vec<GalleryItem>,
pub gallery: Vec<LegacyGalleryItem>,
pub color: Option<u32>,
pub thread_id: ThreadId,
pub monetization_status: MonetizationStatus,
@@ -151,12 +151,12 @@ impl LegacyProject {
id: data.id,
slug: data.slug,
project_type,
team: data.team,
team: data.team_id,
organization: data.organization,
title: data.title,
description: data.description,
body: data.body,
body_url: data.body_url,
title: data.name,
description: data.summary, // V2 description is V3 summary
body: data.description, // V2 body is V3 description
body_url: None, // Always None even in V2
published: data.published,
updated: data.updated,
approved: data.approved,
@@ -177,7 +177,11 @@ impl LegacyProject {
wiki_url,
discord_url,
donation_urls,
gallery: data.gallery,
gallery: data
.gallery
.into_iter()
.map(LegacyGalleryItem::from)
.collect(),
color: data.color,
thread_id: data.thread_id,
monetization_status: data.monetization_status,
@@ -317,7 +321,7 @@ impl From<Version> for LegacyVersion {
name: data.name,
version_number: data.version_number,
changelog: data.changelog,
changelog_url: data.changelog_url,
changelog_url: None, // Always None even in V2
date_published: data.date_published,
downloads: data.downloads,
version_type: data.version_type,
@@ -332,6 +336,29 @@ impl From<Version> for LegacyVersion {
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct LegacyGalleryItem {
pub url: String,
pub featured: bool,
pub name: Option<String>,
pub description: Option<String>,
pub created: DateTime<Utc>,
pub ordering: i64,
}
impl LegacyGalleryItem {
fn from(data: crate::models::projects::GalleryItem) -> Self {
Self {
url: data.url,
featured: data.featured,
name: data.name,
description: data.description,
created: data.created,
ordering: data.ordering,
}
}
}
#[derive(Serialize, Deserialize, Validate, Clone, Eq, PartialEq)]
pub struct DonationLink {
pub id: String,

View File

@@ -109,7 +109,7 @@ impl LegacyResultSearchProject {
project_id: result_search_project.project_id,
slug: result_search_project.slug,
author: result_search_project.author,
title: result_search_project.title,
title: result_search_project.name,
description: result_search_project.description,
display_categories,
downloads: result_search_project.downloads,

41
src/models/v2/teams.rs Normal file
View File

@@ -0,0 +1,41 @@
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use crate::models::{
ids::TeamId,
teams::{ProjectPermissions, TeamMember},
users::User,
};
/// A member of a team
#[derive(Serialize, Deserialize, Clone)]
pub struct LegacyTeamMember {
pub role: String,
// is_owner removed, and role hardcoded to Owner if true,
pub team_id: TeamId,
pub user: User,
pub permissions: Option<ProjectPermissions>,
pub accepted: bool,
#[serde(with = "rust_decimal::serde::float_option")]
pub payouts_split: Option<Decimal>,
pub ordering: i64,
}
impl LegacyTeamMember {
pub fn from(team_member: TeamMember) -> Self {
LegacyTeamMember {
role: match (team_member.is_owner, team_member.role.as_str()) {
(true, _) => "Owner".to_string(),
(false, "Owner") => "Member".to_string(), // The odd case of a non-owner with the owner role should show as 'Member'
(false, role) => role.to_string(),
},
team_id: team_member.team_id,
user: team_member.user,
permissions: team_member.permissions,
accepted: team_member.accepted,
payouts_split: team_member.payouts_split,
ordering: team_member.ordering,
}
}
}