Skip to content

Commit

Permalink
Web Socket Browse Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
wyatt-herkamp committed Jan 28, 2025
1 parent dab1de4 commit 4fb33dc
Show file tree
Hide file tree
Showing 33 changed files with 956 additions and 990 deletions.
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions crates/core/src/database/entities/project/new.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use crate::builder_error::BuilderError;
use crate::repository::project::{ReleaseType, VersionData};
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use sqlx::{types::Json, PgPool};
use tracing::info;
use sqlx::PgPool;
use utoipa::ToSchema;
use uuid::Uuid;

Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/database/entities/project/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use sqlx::{prelude::FromRow, PgPool};
use tracing::debug;
use uuid::Uuid;

use super::{DBProject, ProjectDBType};
use super::ProjectDBType;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, FromRow)]
pub struct ProjectLookupResult {
Expand Down
36 changes: 23 additions & 13 deletions crates/core/src/database/entities/user/permissions.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
use ahash::{HashMap, HashMapExt};

use crate::database::prelude::*;
use serde::{Deserialize, Serialize};
use sqlx::{prelude::FromRow, PgPool};
use tracing::instrument;
use utoipa::ToSchema;
use uuid::Uuid;

use crate::{
database::DateTime,
user::permissions::{RepositoryActions, UserPermissions},
};

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, ToSchema, FromRow)]
use crate::user::permissions::{RepositoryActions, UserPermissions};

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, ToSchema, FromRow, Columns)]
pub struct UserRepositoryPermissions {
pub id: i32,
pub user_id: i32,
pub repository_id: Uuid,
pub actions: Vec<RepositoryActions>,
pub updated_at: chrono::DateTime<chrono::FixedOffset>,
pub created_at: chrono::DateTime<chrono::FixedOffset>,
pub updated_at: DateTime<FixedOffset>,
pub created_at: DateTime<FixedOffset>,
}
impl TableType for UserRepositoryPermissions {
type Columns = UserRepositoryPermissionsColumn;

fn table_name() -> &'static str
where
Self: Sized,
{
"user_repository_permissions"
}
}
impl UserRepositoryPermissions {
pub async fn has_repository_action(
Expand All @@ -28,13 +35,16 @@ impl UserRepositoryPermissions {
action: RepositoryActions,
database: &PgPool,
) -> sqlx::Result<bool> {
let Some(actions) = sqlx::query_scalar::<_, Vec<RepositoryActions>>(
r#"SELECT * FROM user_repository_permissions WHERE user_id = $1 AND repository_id = $2 "#,
let select = SimpleSelectQueryBuilder::new(
Self::table_name(),
vec![UserRepositoryPermissionsColumn::Actions],
)
.bind(user_id)
.bind(repository)
.where_equals(UserRepositoryPermissionsColumn::UserId, user_id)
.where_equals(UserRepositoryPermissionsColumn::RepositoryId, repository)
.query_scalar::<Vec<RepositoryActions>>()
.fetch_optional(database)
.await? else{
.await?;
let Some(actions) = select else {
return Ok(false);
};
Ok(actions.contains(&action))
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/logging/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use ahash::{HashMap, HashMapExt};
use ahash::HashMap;
use serde::{Deserialize, Serialize};
use tracing::level_filters::LevelFilter;
use tracing_subscriber::filter::Targets;
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/repository/project/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use strum::{Display, EnumIs, EnumString, IntoStaticStr};
use utoipa::ToSchema;
use uuid::Uuid;

use crate::database::entities::project::{DBProject, ProjectIds};
use crate::database::entities::project::ProjectIds;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema, Builder, Default)]
pub struct ProjectResolution {
pub project_id: Option<Uuid>,
Expand Down
13 changes: 13 additions & 0 deletions crates/core/src/user/permissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use uuid::Uuid;
use crate::database::entities::user::{
auth_token::AuthToken,
permissions::{NewUserRepositoryPermissions, UserRepositoryPermissions},
UserType,
};

use super::scopes::NRScope;
Expand Down Expand Up @@ -49,6 +50,18 @@ impl<HS: HasPermissions> HasPermissions for Option<HS> {
self.as_ref().and_then(HasPermissions::user_id)
}
}
pub trait HasUserType {
type UserType: UserType;

fn user(&self) -> Option<&Self::UserType>;
}
impl<HS: HasUserType> HasUserType for Option<HS> {
type UserType = HS::UserType;

fn user(&self) -> Option<&Self::UserType> {
self.as_ref().and_then(HasUserType::user)
}
}
pub trait HasPermissions {
fn user_id(&self) -> Option<i32>;
/// Get the permissions of the user. If the user or not logged in, return None
Expand Down
17 changes: 0 additions & 17 deletions crates/nr-api/src/browse.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,2 @@
use bytes::Bytes;
use futures::Stream;

pub struct BrowseStream<S: Stream<Item = reqwest::Result<Bytes>>> {
pub stream: S,
}
impl<S> Stream for BrowseStream<S>
where
S: Stream<Item = reqwest::Result<Bytes>>,
{
type Item = reqwest::Result<Bytes>;

fn poll_next(
self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Option<Self::Item>> {
todo!()
}
}
7 changes: 2 additions & 5 deletions crates/nr-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl NrApi {

#[cfg(test)]
mod tests {
use core::num;

use std::sync::{atomic::AtomicUsize, Arc};

use nr_core::repository::browse::BrowseFile;
Expand Down Expand Up @@ -184,10 +184,7 @@ mod tests {
debug!(?entry, "Found Entry");

match entry {
BrowseFile::Directory {
name,
number_of_files,
} => {
BrowseFile::Directory { name, .. } => {
let next_path = format!("{}/{}", path, name);
Box::pin(recursive_browse(
api.clone(),
Expand Down
1 change: 1 addition & 0 deletions crates/storage/src/dyn_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ impl Storage for DynStorage {
.map_err(Into::into),
}
}

async fn stream_directory(
&self,
repository: Uuid,
Expand Down
4 changes: 2 additions & 2 deletions crates/storage/src/fs/file.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{fmt::Debug, fs::File, io, path::Path};

use crate::{is_hidden_file, local::error::LocalStorageError, LocationMeta, LocationTypedMeta};
use crate::{local::error::LocalStorageError, LocationMeta, LocationTypedMeta};

use super::StorageFileReader;
use chrono::{DateTime, FixedOffset};
Expand Down Expand Up @@ -177,7 +177,7 @@ impl StorageFileMeta<FileFileType> {
}

impl<FT> StorageFileMeta<FT> {
fn map_type<T>(self, f: impl FnOnce(FT) -> T) -> StorageFileMeta<T> {
pub(crate) fn map_type<T>(self, f: impl FnOnce(FT) -> T) -> StorageFileMeta<T> {
StorageFileMeta {
name: self.name,
file_type: f(self.file_type),
Expand Down
3 changes: 0 additions & 3 deletions crates/storage/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@ mod file_meta;
pub(crate) mod path;
pub(crate) mod utils;
pub use content::*;
use derive_more::{derive::Deref, From, Into};
pub use file::*;
pub use file_meta::*;
pub use path::{ExtensionError, ParentDirectoryDoesNotExist};
mod file_reader;
pub use file_reader::*;
use nr_core::storage::StoragePath;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use thiserror::Error;
use utoipa::ToSchema;

/// If you have two paths
/// /a/b and /a/b/c
Expand Down
11 changes: 7 additions & 4 deletions crates/storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub mod s3;
pub use config::*;
pub use error::StorageError;
pub use fs::*;
use futures::{future::BoxFuture, Stream};
use futures::future::BoxFuture;
use meta::RepositoryMeta;
use nr_core::storage::StoragePath;
pub use uuid::Uuid;
Expand Down Expand Up @@ -75,14 +75,17 @@ pub trait Storage: Send + Sync {
) -> impl Future<Output = Result<Option<StorageFileMeta<FileType>>, Self::Error>> + Send;

/// Gets the File Information and Content
///
/// range is ignored for directories
/// range is the byte range to read from the file
fn open_file(
&self,
repository: Uuid,
location: &StoragePath,
) -> impl Future<Output = Result<Option<StorageFile>, Self::Error>> + Send;
/// Streams a list of files in a directory
///
/// # Note
/// Calling this on a file will return a stream with a single file
///
/// This will not return hidden files
fn stream_directory(
&self,
repository: Uuid,
Expand Down
29 changes: 17 additions & 12 deletions crates/storage/src/local/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::{
fs::{self, Metadata},
fs::{self},
io::{self, ErrorKind},
ops::Deref,
path::PathBuf,
Expand All @@ -12,7 +12,6 @@ use error::LocalStorageError;
use nr_core::storage::StoragePath;
use serde::{Deserialize, Serialize};
use tokio::{sync::Mutex, task::JoinSet};
use tokio_stream::wrappers::ReadDirStream;
use tracing::{
debug, debug_span, error, event,
field::{debug, Empty},
Expand Down Expand Up @@ -560,25 +559,31 @@ impl Storage for LocalStorage {
location: &StoragePath,
) -> Result<Option<Self::DirectoryStream>, Self::Error> {
let path = self.get_path(&repository, location);
{
let stream = {
let meta = path.metadata();
match meta {
Ok(meta) if meta.is_dir() => {}
Ok(_) => return Err(LocalStorageError::expected_directory()),
Ok(meta) if meta.is_dir() => {
let meta = StorageFileMeta::read_from_directory(&path)?;

let read_dir = tokio::fs::read_dir(&path).await?;
LocalDirectoryListStream::new_directory(read_dir, meta)
}
Ok(_) => {
if is_hidden_file(&path) {
return Ok(None);
}
let meta = StorageFileMeta::read_from_file(&path)?;

LocalDirectoryListStream::new_file(path, meta)
}
Err(err) if err.kind() == ErrorKind::NotFound => {
return Ok(None);
}
Err(err) => {
return Err(LocalStorageError::IOError(err));
}
}
}

let meta = StorageFileMeta::read_from_directory(&path)?;

let read_dir = tokio::fs::read_dir(&path).await?;
let stream = LocalDirectoryListStream::new_directory(read_dir, meta);

};
Ok(Some(stream))
}
}
Expand Down
23 changes: 15 additions & 8 deletions crates/storage/src/local/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,36 @@ use tracing::trace;

use crate::{
is_hidden_file, local::error::LocalStorageError, streaming::DirectoryListStream,
DirectoryFileType, FileType, StorageError, StorageFileMeta,
DirectoryFileType, FileFileType, FileType, StorageError, StorageFileMeta,
};

#[derive(Debug)]
#[pin_project]
pub struct LocalDirectoryListStream {
#[pin]
files: FileOrDirectory,
meta: StorageFileMeta<DirectoryFileType>,
meta: StorageFileMeta<FileType>,
}
impl LocalDirectoryListStream {
pub fn new_directory(read_dir: ReadDir, meta: StorageFileMeta<DirectoryFileType>) -> Self {
LocalDirectoryListStream {
files: FileOrDirectory::Directory(ReadDirStream::new(read_dir)),
meta,
meta: meta.map_type(|directory_file_type| FileType::Directory(directory_file_type)),
}
}
pub fn new_file(file_path: PathBuf, meta: StorageFileMeta<FileFileType>) -> Self {
LocalDirectoryListStream {
files: FileOrDirectory::File(Some(file_path)),
meta: meta.map_type(|meta| FileType::File(meta)),
}
}
}
impl DirectoryListStream for LocalDirectoryListStream {
fn number_of_files(&self) -> u64 {
self.meta.file_type().file_count
match &self.meta.file_type() {
FileType::Directory(dir) => dir.file_count,
_ => 1,
}
}
}
#[derive(Debug)]
Expand Down Expand Up @@ -82,9 +91,7 @@ impl Stream for LocalDirectoryListStream {
}

fn size_hint(&self) -> (usize, Option<usize>) {
(
self.meta.file_type().file_count as usize,
Some(self.meta.file_type().file_count as usize),
)
let number_of_files = self.number_of_files();
(number_of_files as usize, Some(number_of_files as usize))
}
}
Loading

0 comments on commit 4fb33dc

Please sign in to comment.