feat: add POST api route for creating mirror repos
parent
cbb04a40e0
commit
d39205b653
|
@ -2,8 +2,12 @@ pub mod query;
|
|||
|
||||
use crate::config::DbConfig;
|
||||
|
||||
use sea_orm::{ConnectionTrait, Database, DbConn};
|
||||
use serde::Serialize;
|
||||
use sea_orm::{
|
||||
ActiveModelTrait,
|
||||
ActiveValue::{NotSet, Set},
|
||||
ConnectionTrait, Database, DbConn, EntityTrait, TransactionTrait,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
type Result<T> = std::result::Result<T, sea_orm::DbErr>;
|
||||
|
||||
|
@ -17,6 +21,61 @@ pub struct FullPackage {
|
|||
files: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum RepoType {
|
||||
Regular,
|
||||
FullMirror { mirrors: Vec<String> },
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct NewRepo {
|
||||
distro_id: i32,
|
||||
name: String,
|
||||
description: Option<String>,
|
||||
#[serde(flatten)]
|
||||
r#type: RepoType,
|
||||
}
|
||||
|
||||
impl NewRepo {
|
||||
pub async fn insert(self, conn: &DbConn) -> crate::Result<entity::repo::Model> {
|
||||
let txn = conn.begin().await?;
|
||||
|
||||
let repo_type = match self.r#type {
|
||||
RepoType::Regular => entity::RepoType::Regular,
|
||||
RepoType::FullMirror { .. } => entity::RepoType::FullMirror,
|
||||
};
|
||||
|
||||
let repo = entity::repo::ActiveModel {
|
||||
id: NotSet,
|
||||
distro_id: Set(self.distro_id),
|
||||
name: Set(self.name),
|
||||
description: Set(self.description),
|
||||
r#type: Set(repo_type),
|
||||
};
|
||||
let model = repo.insert(conn).await?;
|
||||
|
||||
match self.r#type {
|
||||
RepoType::Regular => {}
|
||||
RepoType::FullMirror { mirrors } => {
|
||||
entity::RepoMirror::insert_many(mirrors.into_iter().map(|url| {
|
||||
entity::repo_mirror::ActiveModel {
|
||||
id: NotSet,
|
||||
repo_id: Set(model.id),
|
||||
url: Set(url),
|
||||
}
|
||||
}))
|
||||
.on_empty_do_nothing()
|
||||
.exec(&txn)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
txn.commit().await?;
|
||||
Ok(model)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn connect(conn: &DbConfig) -> crate::Result<DbConn> {
|
||||
match conn {
|
||||
DbConfig::Sqlite {
|
||||
|
|
|
@ -30,9 +30,16 @@ impl Handle {
|
|||
})
|
||||
}
|
||||
|
||||
pub async fn get_or_create_repo(&self, distro: &str, repo: &str) -> crate::Result<i32> {
|
||||
let mut repos = self.state.repos.write().await;
|
||||
pub async fn register_repo(&self, repo_id: i32) -> crate::Result<()> {
|
||||
tokio::fs::create_dir(self.state.repos_dir.join(repo_id.to_string())).await?;
|
||||
|
||||
let mut repos = self.state.repos.write().await;
|
||||
repos.insert(repo_id, Default::default());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_or_create_repo(&self, distro: &str, repo: &str) -> crate::Result<i32> {
|
||||
let distro_id: Option<i32> = entity::Distro::find()
|
||||
.filter(entity::distro::Column::Name.eq(distro))
|
||||
.select_only()
|
||||
|
@ -74,8 +81,7 @@ impl Handle {
|
|||
};
|
||||
let id = new_repo.insert(&self.state.conn).await?.id;
|
||||
|
||||
tokio::fs::create_dir(self.state.repos_dir.join(id.to_string())).await?;
|
||||
repos.insert(id, Default::default());
|
||||
self.register_repo(id).await?;
|
||||
|
||||
id
|
||||
};
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
mod pagination;
|
||||
mod repo;
|
||||
|
||||
use crate::db;
|
||||
use pagination::PaginatedResponse;
|
||||
|
||||
use axum::{
|
||||
extract::{Path, Query, State},
|
||||
http::StatusCode,
|
||||
routing::get,
|
||||
Json, Router,
|
||||
};
|
||||
|
||||
pub fn router() -> Router<crate::Global> {
|
||||
Router::new()
|
||||
.route("/repos", get(get_repos))
|
||||
.route("/repos", get(get_repos).post(post_repo))
|
||||
.route("/repos/:id", get(get_single_repo))
|
||||
.route("/packages", get(get_packages))
|
||||
.route("/packages/:id", get(get_single_package))
|
||||
|
@ -39,6 +41,16 @@ async fn get_single_repo(
|
|||
Ok(Json(repo))
|
||||
}
|
||||
|
||||
async fn post_repo(
|
||||
State(global): State<crate::Global>,
|
||||
Json(repo): Json<crate::db::NewRepo>,
|
||||
) -> crate::Result<(StatusCode, Json<entity::repo::Model>)> {
|
||||
let model = repo.insert(&global.db).await?;
|
||||
global.repo.register_repo(model.id).await?;
|
||||
|
||||
Ok((StatusCode::CREATED, Json(model)))
|
||||
}
|
||||
|
||||
async fn get_packages(
|
||||
State(global): State<crate::Global>,
|
||||
Query(pagination): Query<pagination::Query>,
|
||||
|
|
Loading…
Reference in New Issue