Change index interval, add slug to search documents (#110)

* Change index interval, add slug to search documents

* Allow the removal of '@' for slug get

* Fix

* Remove name and rename side type

* Run prepare
This commit is contained in:
Geometrically
2020-12-13 18:10:58 -07:00
committed by GitHub
parent df5684a9f8
commit f0b73fd696
14 changed files with 486 additions and 533 deletions

View File

@@ -6,7 +6,6 @@ pub struct TeamBuilder {
}
pub struct TeamMemberBuilder {
pub user_id: UserId,
pub name: String,
pub role: String,
pub permissions: Permissions,
pub accepted: bool,
@@ -37,7 +36,6 @@ impl TeamBuilder {
id: team_member_id,
team_id,
user_id: member.user_id,
name: member.name,
role: member.role,
permissions: member.permissions,
accepted: member.accepted,
@@ -45,13 +43,12 @@ impl TeamBuilder {
sqlx::query!(
"
INSERT INTO team_members (id, team_id, user_id, member_name, role, permissions, accepted)
VALUES ($1, $2, $3, $4, $5, $6, $7)
INSERT INTO team_members (id, team_id, user_id, role, permissions, accepted)
VALUES ($1, $2, $3, $4, $5, $6)
",
team_member.id as TeamMemberId,
team_member.team_id as TeamId,
team_member.user_id as UserId,
team_member.name,
team_member.role,
team_member.permissions.bits() as i64,
team_member.accepted,
@@ -76,8 +73,6 @@ pub struct TeamMember {
pub team_id: TeamId,
/// The ID of the user associated with the member
pub user_id: UserId,
/// The name of the user
pub name: String,
pub role: String,
pub permissions: Permissions,
pub accepted: bool,
@@ -96,7 +91,7 @@ impl TeamMember {
let team_members = sqlx::query!(
"
SELECT id, user_id, member_name, role, permissions, accepted
SELECT id, user_id, role, permissions, accepted
FROM team_members
WHERE (team_id = $1 AND accepted = TRUE)
",
@@ -111,7 +106,6 @@ impl TeamMember {
id: TeamMemberId(m.id),
team_id: id,
user_id: UserId(m.user_id),
name: m.member_name,
role: m.role,
permissions: perms,
accepted: m.accepted,
@@ -145,7 +139,7 @@ impl TeamMember {
let team_members = sqlx::query!(
"
SELECT id, team_id, member_name, role, permissions, accepted
SELECT id, team_id, role, permissions, accepted
FROM team_members
WHERE (user_id = $1 AND accepted = TRUE)
",
@@ -160,7 +154,6 @@ impl TeamMember {
id: TeamMemberId(m.id),
team_id: TeamId(m.team_id),
user_id: id,
name: m.member_name,
role: m.role,
permissions: perms,
accepted: m.accepted,
@@ -194,7 +187,7 @@ impl TeamMember {
let team_members = sqlx::query!(
"
SELECT id, team_id, member_name, role, permissions, accepted
SELECT id, team_id, role, permissions, accepted
FROM team_members
WHERE user_id = $1
",
@@ -209,7 +202,6 @@ impl TeamMember {
id: TeamMemberId(m.id),
team_id: TeamId(m.team_id),
user_id: id,
name: m.member_name,
role: m.role,
permissions: perms,
accepted: m.accepted,
@@ -242,7 +234,7 @@ impl TeamMember {
{
let result = sqlx::query!(
"
SELECT id, user_id, member_name, role, permissions, accepted
SELECT id, user_id, role, permissions, accepted
FROM team_members
WHERE (team_id = $1 AND user_id = $2 AND accepted = TRUE)
",
@@ -257,7 +249,6 @@ impl TeamMember {
id: TeamMemberId(m.id),
team_id: id,
user_id,
name: m.member_name,
role: m.role,
permissions: Permissions::from_bits(m.permissions as u64)
.ok_or(super::DatabaseError::BitflagError)?,
@@ -279,7 +270,7 @@ impl TeamMember {
{
let result = sqlx::query!(
"
SELECT id, user_id, member_name, role, permissions, accepted
SELECT id, user_id, role, permissions, accepted
FROM team_members
WHERE (team_id = $1 AND user_id = $2)
",
@@ -294,7 +285,6 @@ impl TeamMember {
id: TeamMemberId(m.id),
team_id: id,
user_id,
name: m.member_name,
role: m.role,
permissions: Permissions::from_bits(m.permissions as u64)
.ok_or(super::DatabaseError::BitflagError)?,
@@ -312,16 +302,14 @@ impl TeamMember {
sqlx::query!(
"
INSERT INTO team_members (
id, user_id, member_name, role, permissions, accepted
id, user_id, role, permissions, accepted
)
VALUES (
$1, $2, $3, $4, $5,
$6
$1, $2, $3, $4, $5
)
",
self.id as TeamMemberId,
self.user_id as UserId,
self.name,
self.role,
self.permissions.bits() as i64,
self.accepted,
@@ -369,7 +357,6 @@ impl TeamMember {
new_permissions: Option<Permissions>,
new_role: Option<String>,
new_accepted: Option<bool>,
new_name: Option<String>,
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
) -> Result<(), super::DatabaseError> {
if let Some(permissions) = new_permissions {
@@ -421,22 +408,6 @@ impl TeamMember {
}
}
if let Some(name) = new_name {
sqlx::query!(
"
UPDATE team_members
SET member_name = $1
WHERE (team_id = $2 AND user_id = $3 AND NOT role = $4)
",
name,
id as TeamId,
user_id as UserId,
crate::models::teams::OWNER_ROLE,
)
.execute(&mut *transaction)
.await?;
}
Ok(())
}
}

View File

@@ -343,6 +343,8 @@ fn check_env_vars() -> bool {
failed |= check_var::<usize>("LOCAL_INDEX_INTERVAL");
failed |= check_var::<usize>("VERSION_INDEX_INTERVAL");
failed |= check_var::<String>("GITHUB_CLIENT_ID");
failed |= check_var::<String>("GITHUB_CLIENT_SECRET");

View File

@@ -69,7 +69,7 @@ pub struct Mod {
#[serde(rename_all = "kebab-case")]
pub enum SideType {
Required,
NoFunctionality,
Optional,
Unsupported,
Unknown,
}
@@ -85,7 +85,7 @@ impl SideType {
pub fn as_str(&self) -> &'static str {
match self {
SideType::Required => "required",
SideType::NoFunctionality => "no-functionality",
SideType::Optional => "optional",
SideType::Unsupported => "unsupported",
SideType::Unknown => "unknown",
}
@@ -94,7 +94,7 @@ impl SideType {
pub fn from_str(string: &str) -> SideType {
match string {
"required" => SideType::Required,
"no-functionality" => SideType::NoFunctionality,
"optional" => SideType::Optional,
"unsupported" => SideType::Unsupported,
_ => SideType::Unknown,
}

View File

@@ -47,8 +47,6 @@ impl Default for Permissions {
pub struct TeamMember {
/// The ID of the user associated with the member
pub user_id: UserId,
/// The name of the user
pub name: String,
/// The role of the user in the team
pub role: String,
/// A bitset containing the user's permissions in this team

View File

@@ -165,7 +165,7 @@ pub async fn mod_create(
&mut transaction,
&***file_host,
&mut uploaded_files,
&***indexing_queue
&***indexing_queue,
)
.await;
@@ -457,7 +457,6 @@ async fn mod_create_inner(
let team = models::team_item::TeamBuilder {
members: vec![models::team_item::TeamMemberBuilder {
user_id: current_user.id.into(),
name: current_user.username.clone(),
role: crate::models::teams::OWNER_ROLE.to_owned(),
permissions: crate::models::teams::Permissions::ALL,
accepted: true,

View File

@@ -3,16 +3,16 @@ use crate::auth::get_user_from_headers;
use crate::database;
use crate::file_hosting::FileHost;
use crate::models;
use crate::models::mods::{DonationLink, License, ModStatus, SearchRequest, SideType};
use crate::models::mods::{DonationLink, License, ModId, ModStatus, SearchRequest, SideType};
use crate::models::teams::Permissions;
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 futures::StreamExt;
use serde::{Deserialize, Serialize};
use sqlx::PgPool;
use std::sync::Arc;
use crate::search::indexing::queue::CreationQueue;
use actix_web::web::Data;
#[get("mod")]
pub async fn mod_search(
@@ -133,13 +133,30 @@ pub async fn mod_slug_get(
#[get("{id}")]
pub async fn mod_get(
req: HttpRequest,
info: web::Path<(models::ids::ModId,)>,
info: web::Path<(String,)>,
pool: web::Data<PgPool>,
) -> Result<HttpResponse, ApiError> {
let id = info.into_inner().0;
let mod_data = database::models::Mod::get_full(id.into(), &**pool)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
let string = info.into_inner().0;
let id_option: Option<ModId> = serde_json::from_str(&*format!("\"{}\"", string)).ok();
let mut mod_data;
if let Some(id) = id_option {
mod_data = database::models::Mod::get_full(id.into(), &**pool)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
if mod_data.is_none() {
mod_data = database::models::Mod::get_full_from_slug(string, &**pool)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
}
} else {
mod_data = database::models::Mod::get_full_from_slug(string, &**pool)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
}
let user_option = get_user_from_headers(req.headers(), &**pool).await.ok();
if let Some(data) = mod_data {
@@ -384,9 +401,11 @@ pub async fn mod_edit(
if mod_item.status.is_searchable() && !status.is_searchable() {
delete_from_index(id.into(), config).await?;
} else if !mod_item.status.is_searchable() && status.is_searchable() {
let index_mod =
crate::search::indexing::local_import::query_one(mod_id.into(), &mut *transaction)
.await?;
let index_mod = crate::search::indexing::local_import::query_one(
mod_id.into(),
&mut *transaction,
)
.await?;
indexing_queue.add(index_mod);
}

View File

@@ -28,7 +28,6 @@ pub async fn team_members_get(
.into_iter()
.map(|data| crate::models::teams::TeamMember {
user_id: data.user_id.into(),
name: data.name,
role: data.role,
permissions: Some(data.permissions),
})
@@ -42,7 +41,6 @@ pub async fn team_members_get(
.into_iter()
.map(|data| crate::models::teams::TeamMember {
user_id: data.user_id.into(),
name: data.name,
role: data.role,
permissions: None,
})
@@ -81,7 +79,6 @@ pub async fn join_team(
None,
None,
Some(true),
None,
&mut transaction,
)
.await?;
@@ -174,7 +171,7 @@ pub async fn add_team_member(
}
}
let new_user = crate::database::models::User::get(member.user_id, &**pool)
crate::database::models::User::get(member.user_id, &**pool)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?
.ok_or_else(|| ApiError::InvalidInputError("An invalid User ID specified".to_string()))?;
@@ -184,7 +181,6 @@ pub async fn add_team_member(
id: new_id,
team_id,
user_id: new_member.user_id.into(),
name: new_user.username,
role: new_member.role.clone(),
permissions: new_member.permissions,
accepted: false,
@@ -205,7 +201,6 @@ pub async fn add_team_member(
pub struct EditTeamMember {
pub permissions: Option<Permissions>,
pub role: Option<String>,
pub name: Option<String>,
}
#[patch("{id}/members/{user_id}")]
@@ -236,31 +231,6 @@ pub async fn edit_team_member(
}
};
// If the only thing being modified is the name, a user can
// modify their own member without extra permissions.
if user_id == current_user.id.into()
&& edit_member.permissions.is_none()
&& edit_member.role.is_none()
{
TeamMember::edit_team_member(
id,
user_id,
None,
None,
None,
edit_member.name.clone(),
&mut transaction,
)
.await?;
transaction
.commit()
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
return Ok(HttpResponse::Ok().body(""));
}
if !member.permissions.contains(Permissions::EDIT_MEMBER) {
return Err(ApiError::CustomAuthenticationError(
"You don't have permission to edit members of this team".to_string(),
@@ -287,7 +257,6 @@ pub async fn edit_team_member(
edit_member.permissions,
edit_member.role.clone(),
None,
edit_member.name.clone(),
&mut transaction,
)
.await?;

View File

@@ -70,13 +70,29 @@ pub async fn user_username_get(
#[get("{id}")]
pub async fn user_get(
info: web::Path<(UserId,)>,
info: web::Path<(String,)>,
pool: web::Data<PgPool>,
) -> Result<HttpResponse, ApiError> {
let id = info.into_inner().0;
let user_data = User::get(id.into(), &**pool)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
let string = info.into_inner().0;
let id_option: Option<UserId> = serde_json::from_str(&*format!("\"{}\"", string)).ok();
let mut user_data;
if let Some(id) = id_option {
user_data = User::get(id.into(), &**pool)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
if user_data.is_none() {
user_data = User::get_from_username(string, &**pool)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
}
} else {
user_data = User::get_from_username(string, &**pool)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
}
if let Some(data) = user_data {
let response = convert_user(data);
@@ -160,7 +176,6 @@ pub async fn teams(
.into_iter()
.map(|data| crate::models::teams::TeamMember {
user_id: data.user_id.into(),
name: data.name,
role: data.role,
permissions: if same_user {
Some(data.permissions)

View File

@@ -36,8 +36,12 @@ pub fn schedule_versions(
pool: sqlx::Pool<sqlx::Postgres>,
skip_initial: bool,
) {
// Check mojang's versions every 6 hours
let version_index_interval = std::time::Duration::from_secs(60 * 60 * 6);
let version_index_interval = std::time::Duration::from_secs(
dotenv::var("VERSION_INDEX_INTERVAL")
.ok()
.map(|i| i.parse().unwrap())
.unwrap_or(1800),
);
let mut skip = skip_initial;
scheduler.run(version_index_interval, move || {

View File

@@ -14,7 +14,7 @@ pub async fn index_local(pool: PgPool) -> Result<Vec<UploadSearchMod>, IndexingE
let mut mods = sqlx::query!(
"
SELECT m.id, m.title, m.description, m.downloads, m.icon_url, m.body_url, m.published, m.updated, m.team_id, m.status FROM mods m
SELECT m.id, m.title, m.description, m.downloads, m.icon_url, m.body_url, m.published, m.updated, m.team_id, m.status, m.slug FROM mods m
"
).fetch(&pool);
@@ -129,6 +129,7 @@ pub async fn index_local(pool: PgPool) -> Result<Vec<UploadSearchMod>, IndexingE
modified_timestamp: mod_data.updated.timestamp(),
latest_version,
host: Cow::Borrowed("modrinth"),
slug: mod_data.slug,
});
}
}
@@ -142,7 +143,7 @@ pub async fn query_one(
) -> Result<UploadSearchMod, IndexingError> {
let mod_data = sqlx::query!(
"
SELECT m.id, m.title, m.description, m.downloads, m.icon_url, m.body_url, m.published, m.updated, m.team_id
SELECT m.id, m.title, m.description, m.downloads, m.icon_url, m.body_url, m.published, m.updated, m.team_id, m.slug
FROM mods m
WHERE id = $1
",
@@ -241,5 +242,6 @@ pub async fn query_one(
modified_timestamp: mod_data.updated.timestamp(),
latest_version,
host: Cow::Borrowed("modrinth"),
slug: mod_data.slug,
})
}

View File

@@ -62,6 +62,7 @@ pub struct SearchConfig {
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct UploadSearchMod {
pub mod_id: String,
pub slug: Option<String>,
pub author: String,
pub title: String,
pub description: String,
@@ -96,6 +97,7 @@ pub struct SearchResults {
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ResultSearchMod {
pub mod_id: String,
pub slug: Option<String>,
pub author: String,
pub title: String,
pub description: String,