Add tag and namespace model and socket namespace
Signed-off-by: trivernis <trivernis@protonmail.com>pull/4/head
parent
4cebfc7eb2
commit
17edb0a72f
@ -0,0 +1,7 @@
|
|||||||
|
/// Parses a normalized tag into its two components of namespace and tag
|
||||||
|
pub fn parse_namespace_and_tag(norm_tag: String) -> (Option<String>, String) {
|
||||||
|
norm_tag
|
||||||
|
.split_once(':')
|
||||||
|
.map(|(n, t)| (Some(n.trim().to_string()), t.trim().to_string()))
|
||||||
|
.unwrap_or((None, norm_tag.trim().to_string()))
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
pub mod file;
|
pub mod file;
|
||||||
pub mod file_type;
|
pub mod file_type;
|
||||||
pub mod hash;
|
pub mod hash;
|
||||||
|
pub mod namespace;
|
||||||
pub mod repo;
|
pub mod repo;
|
||||||
pub mod storage;
|
pub mod storage;
|
||||||
|
pub mod tag;
|
||||||
pub mod thumbnail;
|
pub mod thumbnail;
|
||||||
pub mod type_keys;
|
pub mod type_keys;
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
use mediarepo_core::error::RepoResult;
|
||||||
|
use mediarepo_database::entities::namespace;
|
||||||
|
use sea_orm::prelude::*;
|
||||||
|
use sea_orm::{DatabaseConnection, Set};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Namespace {
|
||||||
|
db: DatabaseConnection,
|
||||||
|
model: namespace::Model,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Namespace {
|
||||||
|
pub(crate) fn new(db: DatabaseConnection, model: namespace::Model) -> Self {
|
||||||
|
Self { db, model }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieves the namespace by id
|
||||||
|
pub async fn by_id(db: DatabaseConnection, id: i64) -> RepoResult<Option<Self>> {
|
||||||
|
let namespace = namespace::Entity::find_by_id(id)
|
||||||
|
.one(&db)
|
||||||
|
.await?
|
||||||
|
.map(|model| Self::new(db, model));
|
||||||
|
|
||||||
|
Ok(namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieves a namespace by its name
|
||||||
|
pub async fn by_name<S: AsRef<str>>(
|
||||||
|
db: DatabaseConnection,
|
||||||
|
name: S,
|
||||||
|
) -> RepoResult<Option<Self>> {
|
||||||
|
let namespace = namespace::Entity::find()
|
||||||
|
.filter(namespace::Column::Name.eq(name.as_ref()))
|
||||||
|
.one(&db)
|
||||||
|
.await?
|
||||||
|
.map(|model| Self::new(db, model));
|
||||||
|
|
||||||
|
Ok(namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds a namespace to the database
|
||||||
|
pub async fn add<S: ToString>(db: DatabaseConnection, name: S) -> RepoResult<Self> {
|
||||||
|
let active_model = namespace::ActiveModel {
|
||||||
|
name: Set(name.to_string()),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let active_model = active_model.insert(&db).await?;
|
||||||
|
let namespace = Self::by_id(db, active_model.id.unwrap()).await?.unwrap();
|
||||||
|
|
||||||
|
Ok(namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The ID of the namespace
|
||||||
|
pub fn id(&self) -> i64 {
|
||||||
|
self.model.id
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The name of the namespace
|
||||||
|
pub fn name(&self) -> &String {
|
||||||
|
&self.model.name
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,119 @@
|
|||||||
|
use crate::namespace::Namespace;
|
||||||
|
use mediarepo_core::error::RepoResult;
|
||||||
|
use mediarepo_database::entities::namespace;
|
||||||
|
use mediarepo_database::entities::tag;
|
||||||
|
use sea_orm::prelude::*;
|
||||||
|
use sea_orm::QuerySelect;
|
||||||
|
use sea_orm::{DatabaseConnection, JoinType, Set};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Tag {
|
||||||
|
db: DatabaseConnection,
|
||||||
|
model: tag::Model,
|
||||||
|
namespace: Option<namespace::Model>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tag {
|
||||||
|
pub(crate) fn new(
|
||||||
|
db: DatabaseConnection,
|
||||||
|
model: tag::Model,
|
||||||
|
namespace: Option<namespace::Model>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
db,
|
||||||
|
model,
|
||||||
|
namespace,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns all tags stored in the database
|
||||||
|
pub async fn all(db: DatabaseConnection) -> RepoResult<Vec<Self>> {
|
||||||
|
let tags: Vec<Self> = tag::Entity::find()
|
||||||
|
.find_also_related(namespace::Entity)
|
||||||
|
.all(&db)
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.map(|(tag, namespace)| Self::new(db.clone(), tag, namespace))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the tag by id
|
||||||
|
pub async fn by_id(db: DatabaseConnection, id: i64) -> RepoResult<Option<Self>> {
|
||||||
|
let tag = tag::Entity::find_by_id(id)
|
||||||
|
.find_also_related(namespace::Entity)
|
||||||
|
.one(&db)
|
||||||
|
.await?
|
||||||
|
.map(|(model, namespace)| Self::new(db, model, namespace));
|
||||||
|
|
||||||
|
Ok(tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieves the unnamespaced tag by name
|
||||||
|
pub async fn by_name<S: AsRef<str>>(
|
||||||
|
db: DatabaseConnection,
|
||||||
|
name: S,
|
||||||
|
) -> RepoResult<Option<Self>> {
|
||||||
|
let tag = tag::Entity::find()
|
||||||
|
.filter(tag::Column::Name.eq(name.as_ref()))
|
||||||
|
.filter(tag::Column::NamespaceId.eq(Option::<i64>::None))
|
||||||
|
.one(&db)
|
||||||
|
.await?
|
||||||
|
.map(|t| Tag::new(db, t, None));
|
||||||
|
|
||||||
|
Ok(tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieves the namespaced tag by name and namespace
|
||||||
|
pub async fn by_name_and_namespace<S1: AsRef<str>, S2: AsRef<str>>(
|
||||||
|
db: DatabaseConnection,
|
||||||
|
name: S1,
|
||||||
|
namespace: S2,
|
||||||
|
) -> RepoResult<Option<Self>> {
|
||||||
|
let tag = tag::Entity::find()
|
||||||
|
.find_also_related(namespace::Entity)
|
||||||
|
.join(JoinType::InnerJoin, namespace::Relation::Tag.def())
|
||||||
|
.filter(namespace::Column::Name.eq(namespace.as_ref()))
|
||||||
|
.filter(tag::Column::Name.eq(name.as_ref()))
|
||||||
|
.one(&db)
|
||||||
|
.await?
|
||||||
|
.map(|(t, n)| Self::new(db.clone(), t, n));
|
||||||
|
|
||||||
|
Ok(tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds a new tag to the database
|
||||||
|
pub async fn add<S: ToString>(
|
||||||
|
db: DatabaseConnection,
|
||||||
|
name: S,
|
||||||
|
namespace_id: Option<i64>,
|
||||||
|
) -> RepoResult<Self> {
|
||||||
|
let active_model = tag::ActiveModel {
|
||||||
|
name: Set(name.to_string()),
|
||||||
|
namespace_id: Set(namespace_id),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let active_model = active_model.insert(&db).await?;
|
||||||
|
let tag = Self::by_id(db, active_model.id.unwrap()).await?.unwrap();
|
||||||
|
|
||||||
|
Ok(tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The ID of the tag
|
||||||
|
pub fn id(&self) -> i64 {
|
||||||
|
self.model.id
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The name of the tag
|
||||||
|
pub fn name(&self) -> &String {
|
||||||
|
&self.model.name
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The namespace of the tag
|
||||||
|
pub fn namespace(&self) -> Option<Namespace> {
|
||||||
|
self.namespace
|
||||||
|
.clone()
|
||||||
|
.map(|n| Namespace::new(self.db.clone(), n))
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,10 @@
|
|||||||
use mediarepo_core::rmp_ipc::{namespace, namespace::Namespace, IPCBuilder};
|
use mediarepo_core::rmp_ipc::{namespace, namespace::Namespace, IPCBuilder};
|
||||||
|
|
||||||
pub mod files;
|
pub mod files;
|
||||||
|
pub mod tags;
|
||||||
|
|
||||||
pub fn build_namespaces(builder: IPCBuilder) -> IPCBuilder {
|
pub fn build_namespaces(builder: IPCBuilder) -> IPCBuilder {
|
||||||
builder.add_namespace(namespace!(files::FilesNamespace))
|
builder
|
||||||
|
.add_namespace(namespace!(files::FilesNamespace))
|
||||||
|
.add_namespace(namespace!(tags::TagsNamespace))
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
use crate::types::responses::TagResponse;
|
||||||
|
use crate::utils::get_repo_from_context;
|
||||||
|
use mediarepo_core::rmp_ipc::prelude::*;
|
||||||
|
|
||||||
|
pub struct TagsNamespace;
|
||||||
|
|
||||||
|
impl NamespaceProvider for TagsNamespace {
|
||||||
|
fn name() -> &'static str {
|
||||||
|
"tags"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register(handler: &mut EventHandler) {
|
||||||
|
events!(handler,
|
||||||
|
"all_tags" => Self::all_tags
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TagsNamespace {
|
||||||
|
async fn all_tags(ctx: &Context, event: Event) -> IPCResult<()> {
|
||||||
|
let repo = get_repo_from_context(ctx).await;
|
||||||
|
let tags: Vec<TagResponse> = repo
|
||||||
|
.tags()
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.map(TagResponse::from)
|
||||||
|
.collect();
|
||||||
|
ctx.emitter
|
||||||
|
.emit_response_to(event.id(), Self::name(), "all_tags", tags)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue