You've already forked AstralRinth
forked from didirus/AstralRinth
Fix primary files, file deletion, checks for mod following, fix user following route (#175)
This commit is contained in:
@@ -186,7 +186,11 @@ impl User {
|
||||
Ok(users)
|
||||
}
|
||||
|
||||
pub async fn get_mods<'a, E>(user_id: UserId, exec: E) -> Result<Vec<ModId>, sqlx::Error>
|
||||
pub async fn get_mods<'a, E>(
|
||||
user_id: UserId,
|
||||
status: &str,
|
||||
exec: E,
|
||||
) -> Result<Vec<ModId>, sqlx::Error>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
|
||||
{
|
||||
@@ -196,9 +200,10 @@ impl User {
|
||||
"
|
||||
SELECT m.id FROM mods m
|
||||
INNER JOIN team_members tm ON tm.team_id = m.team_id
|
||||
WHERE tm.user_id = $1
|
||||
WHERE tm.user_id = $1 AND m.status = (SELECT s.id FROM statuses s WHERE s.status = $2)
|
||||
",
|
||||
user_id as UserId,
|
||||
status,
|
||||
)
|
||||
.fetch_many(exec)
|
||||
.try_filter_map(|e| async { Ok(e.right().map(|m| ModId(m.id))) })
|
||||
|
||||
@@ -543,7 +543,7 @@ impl Version {
|
||||
url: file[3].to_string(),
|
||||
filename: file[1].to_string(),
|
||||
hashes: file_hashes,
|
||||
primary: file[3].parse().unwrap_or(false),
|
||||
primary: file[2].parse().unwrap_or(false),
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::routes::ApiError;
|
||||
use crate::search::indexing::queue::CreationQueue;
|
||||
use crate::search::{search_for_mod, SearchConfig, SearchError};
|
||||
use actix_web::web::Data;
|
||||
use actix_web::{delete, get, patch, web, HttpRequest, HttpResponse};
|
||||
use actix_web::{delete, get, patch, post, web, HttpRequest, HttpResponse};
|
||||
use futures::StreamExt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::PgPool;
|
||||
@@ -986,7 +986,7 @@ pub async fn mod_delete(
|
||||
}
|
||||
}
|
||||
|
||||
#[get("{id}/follow")]
|
||||
#[post("{id}/follow")]
|
||||
pub async fn mod_follow(
|
||||
req: HttpRequest,
|
||||
info: web::Path<(models::ids::ModId,)>,
|
||||
@@ -1003,31 +1003,50 @@ pub async fn mod_follow(
|
||||
let user_id: database::models::ids::UserId = user.id.into();
|
||||
let mod_id: database::models::ids::ModId = id.into();
|
||||
|
||||
sqlx::query!(
|
||||
let following = sqlx::query!(
|
||||
"
|
||||
UPDATE mods
|
||||
SET follows = follows + 1
|
||||
WHERE id = $1
|
||||
",
|
||||
mod_id as database::models::ids::ModId,
|
||||
)
|
||||
.execute(&**pool)
|
||||
.await
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||
|
||||
sqlx::query!(
|
||||
"
|
||||
INSERT INTO mod_follows (follower_id, mod_id)
|
||||
VALUES ($1, $2)
|
||||
SELECT EXISTS(SELECT 1 FROM mod_follows mf WHERE mf.follower_id = $1 AND mf.mod_id = $2)
|
||||
",
|
||||
user_id as database::models::ids::UserId,
|
||||
mod_id as database::models::ids::ModId
|
||||
)
|
||||
.execute(&**pool)
|
||||
.fetch_one(&**pool)
|
||||
.await
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?
|
||||
.exists
|
||||
.unwrap_or(false);
|
||||
|
||||
Ok(HttpResponse::Ok().body(""))
|
||||
if !following {
|
||||
sqlx::query!(
|
||||
"
|
||||
UPDATE mods
|
||||
SET follows = follows + 1
|
||||
WHERE id = $1
|
||||
",
|
||||
mod_id as database::models::ids::ModId,
|
||||
)
|
||||
.execute(&**pool)
|
||||
.await
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||
|
||||
sqlx::query!(
|
||||
"
|
||||
INSERT INTO mod_follows (follower_id, mod_id)
|
||||
VALUES ($1, $2)
|
||||
",
|
||||
user_id as database::models::ids::UserId,
|
||||
mod_id as database::models::ids::ModId
|
||||
)
|
||||
.execute(&**pool)
|
||||
.await
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||
|
||||
Ok(HttpResponse::Ok().body(""))
|
||||
} else {
|
||||
Err(ApiError::InvalidInputError(
|
||||
"You are already following this mod!".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[delete("{id}/follow")]
|
||||
@@ -1042,31 +1061,50 @@ pub async fn mod_unfollow(
|
||||
let user_id: database::models::ids::UserId = user.id.into();
|
||||
let mod_id: database::models::ids::ModId = id.into();
|
||||
|
||||
sqlx::query!(
|
||||
let following = sqlx::query!(
|
||||
"
|
||||
UPDATE mods
|
||||
SET follows = follows - 1
|
||||
WHERE id = $1
|
||||
",
|
||||
mod_id as database::models::ids::ModId,
|
||||
)
|
||||
.execute(&**pool)
|
||||
.await
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||
|
||||
sqlx::query!(
|
||||
"
|
||||
DELETE FROM mod_follows
|
||||
WHERE follower_id = $1 AND mod_id = $2
|
||||
SELECT EXISTS(SELECT 1 FROM mod_follows mf WHERE mf.follower_id = $1 AND mf.mod_id = $2)
|
||||
",
|
||||
user_id as database::models::ids::UserId,
|
||||
mod_id as database::models::ids::ModId
|
||||
)
|
||||
.execute(&**pool)
|
||||
.fetch_one(&**pool)
|
||||
.await
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?
|
||||
.exists
|
||||
.unwrap_or(false);
|
||||
|
||||
Ok(HttpResponse::Ok().body(""))
|
||||
if following {
|
||||
sqlx::query!(
|
||||
"
|
||||
UPDATE mods
|
||||
SET follows = follows - 1
|
||||
WHERE id = $1
|
||||
",
|
||||
mod_id as database::models::ids::ModId,
|
||||
)
|
||||
.execute(&**pool)
|
||||
.await
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||
|
||||
sqlx::query!(
|
||||
"
|
||||
DELETE FROM mod_follows
|
||||
WHERE follower_id = $1 AND mod_id = $2
|
||||
",
|
||||
user_id as database::models::ids::UserId,
|
||||
mod_id as database::models::ids::ModId
|
||||
)
|
||||
.execute(&**pool)
|
||||
.await
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||
|
||||
Ok(HttpResponse::Ok().body(""))
|
||||
} else {
|
||||
Err(ApiError::InvalidInputError(
|
||||
"You are not following this mod!".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn delete_from_index(
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use crate::auth::get_user_from_headers;
|
||||
use crate::database::models::User;
|
||||
use crate::file_hosting::FileHost;
|
||||
use crate::models::ids::NotificationId;
|
||||
use crate::models::ids::ModId;
|
||||
use crate::models::mods::ModStatus;
|
||||
use crate::models::notifications::Notification;
|
||||
use crate::models::users::{Role, UserId};
|
||||
use crate::routes::notifications::convert_notification;
|
||||
@@ -136,7 +137,7 @@ pub async fn mods_list(
|
||||
.exists;
|
||||
|
||||
if user_exists.unwrap_or(false) {
|
||||
let mod_data = User::get_mods(id, &**pool)
|
||||
let mod_data = User::get_mods(id, ModStatus::Approved.as_str(), &**pool)
|
||||
.await
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||
|
||||
@@ -371,7 +372,6 @@ pub async fn user_icon_edit(
|
||||
.execute(&**pool)
|
||||
.await
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||
|
||||
Ok(HttpResponse::Ok().body(""))
|
||||
} else {
|
||||
Err(ApiError::InvalidInputError(format!(
|
||||
@@ -443,20 +443,20 @@ pub async fn user_follows(
|
||||
use futures::TryStreamExt;
|
||||
|
||||
let user_id: crate::database::models::UserId = id.into();
|
||||
let notifications: Vec<NotificationId> = sqlx::query!(
|
||||
let mods: Vec<ModId> = sqlx::query!(
|
||||
"
|
||||
SELECT n.id FROM notifications n
|
||||
WHERE n.user_id = $1
|
||||
",
|
||||
SELECT mf.mod_id FROM mod_follows mf
|
||||
WHERE mf.follower_id = $1
|
||||
",
|
||||
user_id as crate::database::models::ids::UserId,
|
||||
)
|
||||
.fetch_many(&**pool)
|
||||
.try_filter_map(|e| async { Ok(e.right().map(|m| NotificationId(m.id as u64))) })
|
||||
.try_collect::<Vec<NotificationId>>()
|
||||
.try_filter_map(|e| async { Ok(e.right().map(|m| ModId(m.mod_id as u64))) })
|
||||
.try_collect::<Vec<ModId>>()
|
||||
.await
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(notifications))
|
||||
Ok(HttpResponse::Ok().json(mods))
|
||||
}
|
||||
|
||||
#[get("{id}/notifications")]
|
||||
|
||||
@@ -450,8 +450,9 @@ pub async fn version_edit(
|
||||
if let Some(primary_file) = &new_version.primary_file {
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
SELECT f.id FROM files f
|
||||
INNER JOIN hashes h ON h.hash = $1 AND h.algorithm = $2
|
||||
SELECT f.id id FROM hashes h
|
||||
INNER JOIN files f ON h.file_id = f.id
|
||||
WHERE h.algorithm = $2 AND h.hash = $1
|
||||
",
|
||||
primary_file.1.as_bytes(),
|
||||
primary_file.0
|
||||
@@ -779,11 +780,10 @@ pub async fn delete_file(
|
||||
|
||||
sqlx::query!(
|
||||
"
|
||||
DELETE FROM hashes
|
||||
WHERE hash = $1 AND algorithm = $2
|
||||
",
|
||||
hash.as_bytes(),
|
||||
algorithm.algorithm
|
||||
DELETE FROM hashes
|
||||
WHERE file_id = $1
|
||||
",
|
||||
row.id
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
.await
|
||||
@@ -791,9 +791,9 @@ pub async fn delete_file(
|
||||
|
||||
sqlx::query!(
|
||||
"
|
||||
DELETE FROM files
|
||||
WHERE files.id = $1
|
||||
",
|
||||
DELETE FROM files
|
||||
WHERE files.id = $1
|
||||
",
|
||||
row.id,
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
|
||||
Reference in New Issue
Block a user