Sanity checked all of V2 route conversions (#803)

* follows

* all v2 routes now either convert or have a comment

* added common structs, clippy

* merge fix

---------

Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
This commit is contained in:
Wyatt Verchere
2023-12-19 10:20:32 -08:00
committed by GitHub
parent 9f798559cf
commit d59c522f7f
20 changed files with 636 additions and 78 deletions

View File

@@ -1,4 +1,6 @@
use super::ApiError;
use crate::models::projects::Project;
use crate::models::v2::projects::LegacyProject;
use crate::queue::session::AuthQueue;
use crate::routes::v3;
use crate::{database::redis::RedisPool, routes::v2_reroute};
@@ -28,13 +30,22 @@ pub async fn get_projects(
count: web::Query<ResultCount>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
v3::moderation::get_projects(
let response = v3::moderation::get_projects(
req,
pool,
redis,
pool.clone(),
redis.clone(),
web::Query(v3::moderation::ResultCount { count: count.count }),
session_queue,
)
.await
.or_else(v2_reroute::flatten_404_error)
.or_else(v2_reroute::flatten_404_error)?;
// Convert to V2 projects
match v2_reroute::extract_ok_json::<Vec<Project>>(response).await {
Ok(project) => {
let legacy_projects = LegacyProject::from_many(project, &**pool, &redis).await?;
Ok(HttpResponse::Ok().json(legacy_projects))
}
Err(response) => Ok(response),
}
}

View File

@@ -85,6 +85,7 @@ pub async fn notification_read(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert
v3::notifications::notification_read(req, info, pool, redis, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
@@ -98,6 +99,7 @@ pub async fn notification_delete(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert
v3::notifications::notification_delete(req, info, pool, redis, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
@@ -111,6 +113,7 @@ pub async fn notifications_read(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert
v3::notifications::notifications_read(
req,
web::Query(v3::notifications::NotificationIds { ids: ids.ids }),
@@ -130,6 +133,7 @@ pub async fn notifications_delete(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert
v3::notifications::notifications_delete(
req,
web::Query(v3::notifications::NotificationIds { ids: ids.ids }),

View File

@@ -2,11 +2,10 @@ use crate::database::models::categories::LinkPlatform;
use crate::database::models::{project_item, version_item};
use crate::database::redis::RedisPool;
use crate::file_hosting::FileHost;
use crate::models;
use crate::models::projects::{
Link, MonetizationStatus, Project, ProjectStatus, SearchRequest, Version,
};
use crate::models::v2::projects::{DonationLink, LegacyProject, LegacySideType};
use crate::models::v2::projects::{DonationLink, LegacyProject, LegacySideType, LegacyVersion};
use crate::models::v2::search::LegacySearchResults;
use crate::queue::session::AuthQueue;
use crate::routes::v3::projects::ProjectIds;
@@ -223,6 +222,7 @@ pub async fn project_get_check(
pool: web::Data<PgPool>,
redis: web::Data<RedisPool>,
) -> Result<HttpResponse, ApiError> {
// Returns an id only, do not need to convert
v3::projects::project_get_check(info, pool, redis)
.await
.or_else(v2_reroute::flatten_404_error)
@@ -230,8 +230,8 @@ pub async fn project_get_check(
#[derive(Serialize)]
struct DependencyInfo {
pub projects: Vec<Project>,
pub versions: Vec<models::projects::Version>,
pub projects: Vec<LegacyProject>,
pub versions: Vec<LegacyVersion>,
}
#[get("dependencies")]
@@ -242,10 +242,30 @@ pub async fn dependency_list(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// TODO: requires V2 conversion and tests, probably
v3::projects::dependency_list(req, info, pool, redis, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
// TODO: tests, probably
let response =
v3::projects::dependency_list(req, info, pool.clone(), redis.clone(), session_queue)
.await
.or_else(v2_reroute::flatten_404_error)?;
match v2_reroute::extract_ok_json::<crate::routes::v3::projects::DependencyInfo>(response).await
{
Ok(dependency_info) => {
let converted_projects =
LegacyProject::from_many(dependency_info.projects, &**pool, &redis).await?;
let converted_versions = dependency_info
.versions
.into_iter()
.map(LegacyVersion::from)
.collect();
Ok(HttpResponse::Ok().json(DependencyInfo {
projects: converted_projects,
versions: converted_versions,
}))
}
Err(response) => Ok(response),
}
}
#[derive(Serialize, Deserialize, Validate)]
@@ -636,6 +656,7 @@ pub async fn projects_edit(
}
}
// This returns NoContent or failure so we don't need to do anything with it
v3::projects::projects_edit(
req,
web::Query(ids),
@@ -673,6 +694,7 @@ pub async fn project_icon_edit(
payload: web::Payload,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert
v3::projects::project_icon_edit(
web::Query(v3::projects::Extension { ext: ext.ext }),
req,
@@ -696,6 +718,7 @@ pub async fn delete_project_icon(
file_host: web::Data<Arc<dyn FileHost + Send + Sync>>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert
v3::projects::delete_project_icon(req, info, pool, redis, file_host, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
@@ -724,6 +747,7 @@ pub async fn add_gallery_item(
payload: web::Payload,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert
v3::projects::add_gallery_item(
web::Query(v3::projects::Extension { ext: ext.ext }),
req,
@@ -775,6 +799,7 @@ pub async fn edit_gallery_item(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert
v3::projects::edit_gallery_item(
req,
web::Query(v3::projects::GalleryEditQuery {
@@ -808,6 +833,7 @@ pub async fn delete_gallery_item(
file_host: web::Data<Arc<dyn FileHost + Send + Sync>>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert
v3::projects::delete_gallery_item(
req,
web::Query(v3::projects::GalleryDeleteQuery { url: item.url }),
@@ -830,6 +856,7 @@ pub async fn project_delete(
config: web::Data<SearchConfig>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert
v3::projects::project_delete(req, info, pool, redis, config, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
@@ -843,6 +870,7 @@ pub async fn project_follow(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert
v3::projects::project_follow(req, info, pool, redis, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
@@ -856,6 +884,7 @@ pub async fn project_unfollow(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert
v3::projects::project_unfollow(req, info, pool, redis, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)

View File

@@ -1,6 +1,7 @@
use crate::database::redis::RedisPool;
use crate::models::ids::ImageId;
use crate::models::reports::ItemType;
use crate::models::reports::{ItemType, Report};
use crate::models::v2::reports::LegacyReport;
use crate::queue::session::AuthQueue;
use crate::routes::{v2_reroute, v3, ApiError};
use actix_web::{delete, get, patch, post, web, HttpRequest, HttpResponse};
@@ -37,9 +38,18 @@ pub async fn report_create(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
v3::reports::report_create(req, pool, body, redis, session_queue)
let response = v3::reports::report_create(req, pool, body, redis, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
.or_else(v2_reroute::flatten_404_error)?;
// Convert response to V2 format
match v2_reroute::extract_ok_json::<Report>(response).await {
Ok(report) => {
let report = LegacyReport::from(report);
Ok(HttpResponse::Ok().json(report))
}
Err(response) => Ok(response),
}
}
#[derive(Deserialize)]
@@ -65,7 +75,7 @@ pub async fn reports(
count: web::Query<ReportsRequestOptions>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
v3::reports::reports(
let response = v3::reports::reports(
req,
pool,
redis,
@@ -76,7 +86,16 @@ pub async fn reports(
session_queue,
)
.await
.or_else(v2_reroute::flatten_404_error)
.or_else(v2_reroute::flatten_404_error)?;
// Convert response to V2 format
match v2_reroute::extract_ok_json::<Vec<Report>>(response).await {
Ok(reports) => {
let reports: Vec<_> = reports.into_iter().map(LegacyReport::from).collect();
Ok(HttpResponse::Ok().json(reports))
}
Err(response) => Ok(response),
}
}
#[derive(Deserialize)]
@@ -92,7 +111,7 @@ pub async fn reports_get(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
v3::reports::reports_get(
let response = v3::reports::reports_get(
req,
web::Query(v3::reports::ReportIds { ids: ids.ids }),
pool,
@@ -100,7 +119,16 @@ pub async fn reports_get(
session_queue,
)
.await
.or_else(v2_reroute::flatten_404_error)
.or_else(v2_reroute::flatten_404_error)?;
// Convert response to V2 format
match v2_reroute::extract_ok_json::<Vec<Report>>(response).await {
Ok(report_list) => {
let report_list: Vec<_> = report_list.into_iter().map(LegacyReport::from).collect();
Ok(HttpResponse::Ok().json(report_list))
}
Err(response) => Ok(response),
}
}
#[get("report/{id}")]
@@ -111,9 +139,18 @@ pub async fn report_get(
info: web::Path<(crate::models::reports::ReportId,)>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
v3::reports::report_get(req, pool, redis, info, session_queue)
let response = v3::reports::report_get(req, pool, redis, info, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
.or_else(v2_reroute::flatten_404_error)?;
// Convert response to V2 format
match v2_reroute::extract_ok_json::<Report>(response).await {
Ok(report) => {
let report = LegacyReport::from(report);
Ok(HttpResponse::Ok().json(report))
}
Err(response) => Ok(response),
}
}
#[derive(Deserialize, Validate)]
@@ -133,6 +170,7 @@ pub async fn report_edit(
edit_report: web::Json<EditReport>,
) -> Result<HttpResponse, ApiError> {
let edit_report = edit_report.into_inner();
// Returns NoContent, so no need to convert
v3::reports::report_edit(
req,
pool,
@@ -156,6 +194,7 @@ pub async fn report_delete(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert
v3::reports::report_delete(req, pool, info, redis, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)

View File

@@ -1,4 +1,8 @@
use crate::routes::{v2_reroute, v3, ApiError};
use crate::routes::{
v2_reroute,
v3::{self, statistics::V3Stats},
ApiError,
};
use actix_web::{get, web, HttpResponse};
use sqlx::PgPool;
@@ -6,9 +10,30 @@ pub fn config(cfg: &mut web::ServiceConfig) {
cfg.service(get_stats);
}
#[derive(serde::Serialize)]
pub struct V2Stats {
pub projects: Option<i64>,
pub versions: Option<i64>,
pub authors: Option<i64>,
pub files: Option<i64>,
}
#[get("statistics")]
pub async fn get_stats(pool: web::Data<PgPool>) -> Result<HttpResponse, ApiError> {
v3::statistics::get_stats(pool)
let response = v3::statistics::get_stats(pool)
.await
.or_else(v2_reroute::flatten_404_error)
.or_else(v2_reroute::flatten_404_error)?;
match v2_reroute::extract_ok_json::<V3Stats>(response).await {
Ok(stats) => {
let stats = V2Stats {
projects: stats.projects,
versions: stats.versions,
authors: stats.authors,
files: stats.files,
};
Ok(HttpResponse::Ok().json(stats))
}
Err(response) => Ok(response),
}
}

View File

@@ -5,9 +5,7 @@ use crate::database::models::loader_fields::LoaderFieldEnumValue;
use crate::database::redis::RedisPool;
use crate::models::v2::projects::LegacySideType;
use crate::routes::v2_reroute::capitalize_first;
use crate::routes::v3::tags::{
LinkPlatformQueryData, LoaderData as LoaderDataV3, LoaderFieldsEnumQuery,
};
use crate::routes::v3::tags::{LinkPlatformQueryData, LoaderFieldsEnumQuery};
use crate::routes::{v2_reroute, v3};
use actix_web::{get, web, HttpResponse};
use chrono::{DateTime, Utc};
@@ -42,7 +40,24 @@ pub async fn category_list(
pool: web::Data<PgPool>,
redis: web::Data<RedisPool>,
) -> Result<HttpResponse, ApiError> {
v3::tags::category_list(pool, redis).await
let response = v3::tags::category_list(pool, redis).await?;
// Convert to V2 format
match v2_reroute::extract_ok_json::<Vec<v3::tags::CategoryData>>(response).await {
Ok(categories) => {
let categories = categories
.into_iter()
.map(|c| CategoryData {
icon: c.icon,
name: c.name,
project_type: c.project_type,
header: c.header,
})
.collect::<Vec<_>>();
Ok(HttpResponse::Ok().json(categories))
}
Err(response) => Ok(response),
}
}
#[derive(serde::Serialize, serde::Deserialize)]
@@ -60,7 +75,7 @@ pub async fn loader_list(
let response = v3::tags::loader_list(pool, redis).await?;
// Convert to V2 format
match v2_reroute::extract_ok_json::<Vec<LoaderDataV3>>(response).await {
match v2_reroute::extract_ok_json::<Vec<v3::tags::LoaderData>>(response).await {
Ok(loaders) => {
let loaders = loaders
.into_iter()
@@ -151,26 +166,52 @@ pub async fn game_version_list(
#[derive(serde::Serialize)]
pub struct License {
short: String,
name: String,
pub short: String,
pub name: String,
}
#[get("license")]
pub async fn license_list() -> HttpResponse {
v3::tags::license_list().await
let response = v3::tags::license_list().await;
// Convert to V2 format
match v2_reroute::extract_ok_json::<Vec<v3::tags::License>>(response).await {
Ok(licenses) => {
let licenses = licenses
.into_iter()
.map(|l| License {
short: l.short,
name: l.name,
})
.collect::<Vec<_>>();
HttpResponse::Ok().json(licenses)
}
Err(response) => response,
}
}
#[derive(serde::Serialize)]
pub struct LicenseText {
title: String,
body: String,
pub title: String,
pub body: String,
}
#[get("license/{id}")]
pub async fn license_text(params: web::Path<(String,)>) -> Result<HttpResponse, ApiError> {
v3::tags::license_text(params)
let license = v3::tags::license_text(params)
.await
.or_else(v2_reroute::flatten_404_error)
.or_else(v2_reroute::flatten_404_error)?;
// Convert to V2 format
Ok(
match v2_reroute::extract_ok_json::<v3::tags::LicenseText>(license).await {
Ok(license) => HttpResponse::Ok().json(LicenseText {
title: license.title,
body: license.body,
}),
Err(response) => response,
},
)
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Eq, Debug)]
@@ -229,6 +270,7 @@ pub async fn report_type_list(
pool: web::Data<PgPool>,
redis: web::Data<RedisPool>,
) -> Result<HttpResponse, ApiError> {
// This returns a list of strings directly, so we don't need to convert to v2 format.
v3::tags::report_type_list(pool, redis)
.await
.or_else(v2_reroute::flatten_404_error)
@@ -239,6 +281,7 @@ pub async fn project_type_list(
pool: web::Data<PgPool>,
redis: web::Data<RedisPool>,
) -> Result<HttpResponse, ApiError> {
// This returns a list of strings directly, so we don't need to convert to v2 format.
v3::tags::project_type_list(pool, redis)
.await
.or_else(v2_reroute::flatten_404_error)

View File

@@ -124,6 +124,7 @@ pub async fn join_team(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so we don't need to convert the response
v3::teams::join_team(req, info, pool, redis, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
@@ -162,6 +163,7 @@ pub async fn add_team_member(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so we don't need to convert the response
v3::teams::add_team_member(
req,
info,
@@ -199,6 +201,7 @@ pub async fn edit_team_member(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so we don't need to convert the response
v3::teams::edit_team_member(
req,
info,
@@ -231,6 +234,7 @@ pub async fn transfer_ownership(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so we don't need to convert the response
v3::teams::transfer_ownership(
req,
info,
@@ -253,6 +257,7 @@ pub async fn remove_team_member(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so we don't need to convert the response
v3::teams::remove_team_member(req, info, pool, redis, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)

View File

@@ -3,7 +3,8 @@ use std::sync::Arc;
use crate::database::redis::RedisPool;
use crate::file_hosting::FileHost;
use crate::models::ids::ThreadMessageId;
use crate::models::threads::{MessageBody, ThreadId};
use crate::models::threads::{MessageBody, Thread, ThreadId};
use crate::models::v2::threads::LegacyThread;
use crate::queue::session::AuthQueue;
use crate::routes::{v2_reroute, v3, ApiError};
use actix_web::{delete, get, post, web, HttpRequest, HttpResponse};
@@ -48,7 +49,7 @@ pub async fn threads_get(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
v3::threads::threads_get(
let response = v3::threads::threads_get(
req,
web::Query(v3::threads::ThreadIds { ids: ids.ids }),
pool,
@@ -56,7 +57,19 @@ pub async fn threads_get(
session_queue,
)
.await
.or_else(v2_reroute::flatten_404_error)
.or_else(v2_reroute::flatten_404_error)?;
// Convert response to V2 format
match v2_reroute::extract_ok_json::<Vec<Thread>>(response).await {
Ok(threads) => {
let threads = threads
.into_iter()
.map(LegacyThread::from)
.collect::<Vec<_>>();
Ok(HttpResponse::Ok().json(threads))
}
Err(response) => Ok(response),
}
}
#[derive(Deserialize)]
@@ -74,6 +87,7 @@ pub async fn thread_send_message(
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
let new_message = new_message.into_inner();
// Returns NoContent, so we don't need to convert the response
v3::threads::thread_send_message(
req,
info,
@@ -95,9 +109,21 @@ pub async fn moderation_inbox(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
v3::threads::moderation_inbox(req, pool, redis, session_queue)
let response = v3::threads::moderation_inbox(req, pool, redis, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
.or_else(v2_reroute::flatten_404_error)?;
// Convert response to V2 format
match v2_reroute::extract_ok_json::<Vec<Thread>>(response).await {
Ok(threads) => {
let threads = threads
.into_iter()
.map(LegacyThread::from)
.collect::<Vec<_>>();
Ok(HttpResponse::Ok().json(threads))
}
Err(response) => Ok(response),
}
}
#[post("{id}/read")]
@@ -108,6 +134,7 @@ pub async fn thread_read(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so we don't need to convert the response
v3::threads::thread_read(req, info, pool, redis, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
@@ -122,6 +149,7 @@ pub async fn message_delete(
session_queue: web::Data<AuthQueue>,
file_host: web::Data<Arc<dyn FileHost + Send + Sync>>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so we don't need to convert the response
v3::threads::message_delete(req, info, pool, redis, session_queue, file_host)
.await
.or_else(v2_reroute::flatten_404_error)

View File

@@ -2,9 +2,10 @@ use crate::database::redis::RedisPool;
use crate::file_hosting::FileHost;
use crate::models::notifications::Notification;
use crate::models::projects::Project;
use crate::models::users::{Badges, Role};
use crate::models::users::{Badges, Role, User};
use crate::models::v2::notifications::LegacyNotification;
use crate::models::v2::projects::LegacyProject;
use crate::models::v2::user::LegacyUser;
use crate::queue::session::AuthQueue;
use crate::routes::{v2_reroute, v3, ApiError};
use actix_web::{delete, get, patch, web, HttpRequest, HttpResponse};
@@ -38,9 +39,18 @@ pub async fn user_auth_get(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
v3::users::user_auth_get(req, pool, redis, session_queue)
let response = v3::users::user_auth_get(req, pool, redis, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
.or_else(v2_reroute::flatten_404_error)?;
// Convert response to V2 format
match v2_reroute::extract_ok_json::<User>(response).await {
Ok(user) => {
let user = LegacyUser::from(user);
Ok(HttpResponse::Ok().json(user))
}
Err(response) => Ok(response),
}
}
#[derive(Serialize, Deserialize)]
@@ -54,9 +64,19 @@ pub async fn users_get(
pool: web::Data<PgPool>,
redis: web::Data<RedisPool>,
) -> Result<HttpResponse, ApiError> {
v3::users::users_get(web::Query(v3::users::UserIds { ids: ids.ids }), pool, redis)
.await
.or_else(v2_reroute::flatten_404_error)
let response =
v3::users::users_get(web::Query(v3::users::UserIds { ids: ids.ids }), pool, redis)
.await
.or_else(v2_reroute::flatten_404_error)?;
// Convert response to V2 format
match v2_reroute::extract_ok_json::<Vec<User>>(response).await {
Ok(users) => {
let legacy_users: Vec<LegacyUser> = users.into_iter().map(LegacyUser::from).collect();
Ok(HttpResponse::Ok().json(legacy_users))
}
Err(response) => Ok(response),
}
}
#[get("{id}")]
@@ -65,9 +85,18 @@ pub async fn user_get(
pool: web::Data<PgPool>,
redis: web::Data<RedisPool>,
) -> Result<HttpResponse, ApiError> {
v3::users::user_get(info, pool, redis)
let response = v3::users::user_get(info, pool, redis)
.await
.or_else(v2_reroute::flatten_404_error)
.or_else(v2_reroute::flatten_404_error)?;
// Convert response to V2 format
match v2_reroute::extract_ok_json::<User>(response).await {
Ok(user) => {
let user = LegacyUser::from(user);
Ok(HttpResponse::Ok().json(user))
}
Err(response) => Ok(response),
}
}
#[get("{user_id}/projects")]
@@ -128,6 +157,7 @@ pub async fn user_edit(
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
let new_user = new_user.into_inner();
// Returns NoContent, so we don't need to convert to V2
v3::users::user_edit(
req,
info,
@@ -164,6 +194,7 @@ pub async fn user_icon_edit(
payload: web::Payload,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so we don't need to convert to V2
v3::users::user_icon_edit(
web::Query(v3::users::Extension { ext: ext.ext }),
req,
@@ -186,6 +217,7 @@ pub async fn user_delete(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so we don't need to convert to V2
v3::users::user_delete(req, info, pool, redis, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
@@ -199,9 +231,18 @@ pub async fn user_follows(
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
v3::users::user_follows(req, info, pool, redis, session_queue)
let response = v3::users::user_follows(req, info, pool.clone(), redis.clone(), session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
.or_else(v2_reroute::flatten_404_error)?;
// Convert to V2 projects
match v2_reroute::extract_ok_json::<Vec<Project>>(response).await {
Ok(project) => {
let legacy_projects = LegacyProject::from_many(project, &**pool, &redis).await?;
Ok(HttpResponse::Ok().json(legacy_projects))
}
Err(response) => Ok(response),
}
}
#[get("{id}/notifications")]

View File

@@ -268,6 +268,7 @@ pub async fn upload_file_to_version(
file_host: Data<Arc<dyn FileHost + Send + Sync>>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, CreateError> {
// Returns NoContent, so no need to convert to V2
let response = v3::version_creation::upload_file_to_version(
req,
url_data,

View File

@@ -63,6 +63,7 @@ pub async fn download_version(
hash_query: web::Query<HashQuery>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns TemporaryRedirect, so no need to convert to V2
v3::version_file::download_version(req, info, pool, redis, hash_query, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)
@@ -78,6 +79,7 @@ pub async fn delete_file(
hash_query: web::Query<HashQuery>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so no need to convert to V2
v3::version_file::delete_file(req, info, pool, redis, hash_query, session_queue)
.await
.or_else(v2_reroute::flatten_404_error)

View File

@@ -270,6 +270,7 @@ pub async fn version_delete(
session_queue: web::Data<AuthQueue>,
search_config: web::Data<SearchConfig>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so we don't need to convert the response
v3::versions::version_delete(req, info, pool, redis, session_queue, search_config)
.await
.or_else(v2_reroute::flatten_404_error)
@@ -290,6 +291,7 @@ pub async fn version_schedule(
scheduling_data: web::Json<SchedulingData>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so we don't need to convert the response
let scheduling_data = scheduling_data.into_inner();
let scheduling_data = v3::versions::SchedulingData {
time: scheduling_data.time,

View File

@@ -939,8 +939,8 @@ pub async fn project_get_check(
}
}
#[derive(Serialize)]
struct DependencyInfo {
#[derive(Serialize, Deserialize)]
pub struct DependencyInfo {
pub projects: Vec<Project>,
pub versions: Vec<models::projects::Version>,
}

View File

@@ -1,12 +1,19 @@
use crate::routes::ApiError;
use actix_web::{web, HttpResponse};
use serde_json::json;
use sqlx::PgPool;
pub fn config(cfg: &mut web::ServiceConfig) {
cfg.route("statistics", web::get().to(get_stats));
}
#[derive(serde::Serialize, serde::Deserialize)]
pub struct V3Stats {
pub projects: Option<i64>,
pub versions: Option<i64>,
pub authors: Option<i64>,
pub files: Option<i64>,
}
pub async fn get_stats(pool: web::Data<PgPool>) -> Result<HttpResponse, ApiError> {
let projects = sqlx::query!(
"
@@ -74,12 +81,12 @@ pub async fn get_stats(pool: web::Data<PgPool>) -> Result<HttpResponse, ApiError
.fetch_one(&**pool)
.await?;
let json = json!({
"projects": projects.count,
"versions": versions.count,
"authors": authors.count,
"files": files.count,
});
let v3_stats = V3Stats {
projects: projects.count,
versions: versions.count,
authors: authors.count,
files: files.count,
};
Ok(HttpResponse::Ok().json(json))
Ok(HttpResponse::Ok().json(v3_stats))
}

View File

@@ -166,10 +166,10 @@ pub async fn loader_fields_list(
Ok(HttpResponse::Ok().json(results))
}
#[derive(serde::Serialize)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct License {
short: String,
name: String,
pub short: String,
pub name: String,
}
pub async fn license_list() -> HttpResponse {
@@ -186,10 +186,10 @@ pub async fn license_list() -> HttpResponse {
HttpResponse::Ok().json(results)
}
#[derive(serde::Serialize)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct LicenseText {
title: String,
body: String,
pub title: String,
pub body: String,
}
pub async fn license_text(params: web::Path<(String,)>) -> Result<HttpResponse, ApiError> {