Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions src/database/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ pub enum CategoryError {
#[snafu(display("Database error"))]
DB { source: sea_orm::DbErr },
#[snafu(display("The category (ID: {id}) does not exist"))]
NotFound { id: i32 },
IDNotFound { id: i32 },
#[snafu(display("The category (Name: {name}) does not exist"))]
NameNotFound { name: String },
#[snafu(display("Failed to save the operation log"))]
Logger { source: LoggerError },
}
Expand All @@ -71,6 +73,20 @@ impl CategoryOperator {
.context(DBSnafu)
}

/// Find one category by Name
pub async fn find_by_name(&self, name: String) -> Result<Model, CategoryError> {
let category = Entity::find()
.filter(Column::Name.contains(name.clone()))
.one(&self.state.database)
.await
.context(DBSnafu)?;

match category {
Some(category) => Ok(category),
None => Err(CategoryError::NameNotFound { name }),
}
}

/// Delete a category
pub async fn delete(&self, id: i32, user: Option<User>) -> Result<String, CategoryError> {
let db = &self.state.database;
Expand Down Expand Up @@ -101,7 +117,7 @@ impl CategoryOperator {

Ok(category_clone.name)
}
None => Err(CategoryError::NotFound { id }),
None => Err(CategoryError::IDNotFound { id }),
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ pub fn router(state: state::AppState) -> Router {
Router::new()
// Register dynamic routes
.route("/", get(routes::index::index))
.route("/upload", get(routes::index::upload))
.route("/progress/{view_request}", get(routes::progress::progress))
.route("/categories", get(routes::category::index))
.route("/categories", post(routes::category::create))
.route("/categories/new", get(routes::category::new))
.route("/categories/{id}/delete", get(routes::category::delete))
.route("/folders/{category_id}", get(routes::category::show))
.route("/logs", get(routes::logs::index))
// Register static assets routes
.nest("/assets", static_router())
Expand Down
30 changes: 30 additions & 0 deletions src/routes/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,33 @@ pub async fn index(
},
))
}

#[derive(Template, WebTemplate)]
#[template(path = "categories/show.html")]
pub struct CategoryShowTemplate {
/// Global application state
pub state: AppStateContext,
/// Logged-in user.
pub user: Option<User>,
/// Category
category: category::Model,
}

pub async fn show(
State(app_state): State<AppState>,
user: Option<User>,
Path(category_name): Path<String>,
) -> Result<CategoryShowTemplate, AppStateError> {
let app_state_context = app_state.context().await?;

let category: category::Model = CategoryOperator::new(app_state.clone(), user.clone())
.find_by_name(category_name.to_string())
.await
.context(CategorySnafu)?;

Ok(CategoryShowTemplate {
category,
state: app_state_context,
user,
})
}
39 changes: 37 additions & 2 deletions src/routes/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@ use axum::extract::State;
use snafu::prelude::*;

// TUTORIAL: https://github.com/SeaQL/sea-orm/blob/master/examples/axum_example/
use crate::database::category::CategoryOperator;
use crate::database::category::{self, CategoryOperator};
use crate::extractors::user::User;
use crate::state::{AppState, AppStateContext, error::*};

#[derive(Template, WebTemplate)]
#[template(path = "index.html")]
pub struct IndexTemplate {
/// Global application state (errors/warnings)
pub state: AppStateContext,
/// Logged-in user.
pub user: Option<User>,
/// Categories
pub categories: Vec<category::Model>,
}

#[derive(Template, WebTemplate)]
#[template(path = "upload.html")]
pub struct UploadTemplate {
/// Global application state (errors/warnings)
pub state: AppStateContext,
/// Logged-in user.
Expand All @@ -20,6 +31,23 @@ pub struct IndexTemplate {
}

impl IndexTemplate {
pub async fn new(app_state: AppState, user: Option<User>) -> Result<Self, AppStateError> {
let app_state_context = app_state.context().await?;

let categories = CategoryOperator::new(app_state.clone(), user.clone())
.list()
.await
.context(CategorySnafu)?;

Ok(IndexTemplate {
state: app_state_context,
user,
categories,
})
}
}

impl UploadTemplate {
pub async fn new(app_state: AppState, user: Option<User>) -> Result<Self, AppStateError> {
let categories: Vec<String> = CategoryOperator::new(app_state.clone(), user.clone())
.list()
Expand All @@ -29,7 +57,7 @@ impl IndexTemplate {
.map(|x| x.name)
.collect();

Ok(IndexTemplate {
Ok(UploadTemplate {
state: app_state.context().await?,
user,
categories,
Expand All @@ -43,3 +71,10 @@ pub async fn index(
) -> Result<IndexTemplate, AppStateError> {
IndexTemplate::new(app_state, user).await
}

pub async fn upload(
State(app_state): State<AppState>,
user: Option<User>,
) -> Result<UploadTemplate, AppStateError> {
UploadTemplate::new(app_state, user).await
}
8 changes: 8 additions & 0 deletions templates/categories/dropdown_actions.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Actions
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/categories/new">Create category</a></li>
</ul>
</div>
28 changes: 28 additions & 0 deletions templates/categories/show.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{% extends "layouts/file_system_base.html" %}

{% block breadcrumb %}
<li class="breadcrumb-item">
<a href="/">
Categories
</a>
</li>

<li class="breadcrumb-item">
<a href="/folders/{{ category.name }}">
{{ category.name }}
</a>
</li>
{% endblock %}

{% block folder_title %}
{{ category.name }}
{% endblock%}

{% block additional_buttons %}
<a class="btn btn-dark" href="/">
Go up
</a>
{% endblock %}

{% block system_list %}
{% endblock %}
102 changes: 37 additions & 65 deletions templates/index.html
Original file line number Diff line number Diff line change
@@ -1,71 +1,43 @@
{% extends "base.html" %}

{% block main %}
<div class="container">
<h1>Download files</h1>

{% if state.free_space.free_space_percent < 5 %}
<div class="alert alert-warning mt-4">
The disks are almost full : <span class="fw-bold">{{ state.free_space.free_space_gib }} GiB left</span>
</div>
{% endif %}
{% extends "layouts/file_system_base.html" %}

{% block breadcrumb %}
<li class="breadcrumb-item">
<a href="/">
Categories
</a>
</li>
{% endblock %}

<form method="POST" action="/upload" enctype="multipart/form-data" accept-charset="utf-8">
<div class="card mt-4">
<div class="card-body">
<div class="form-group">
<label for="collection" class="form-label mb-0">Category</label>
<div id="collection" class="form-text mb-1">Choose the type of content you want to download.</div>
<select class="form-select" aria-label="Choose the type of content you want to download" name="collection">{#{% set post_tag = post.tag %} TODO #}
<option disabled {#{% if post_tag is not defined %}selected{% endif %}#}>Genre</option>
{% for tag in categories %}
<option {#{% if post_tag == tag %}selected {% endif %}#}value="{{ tag }}">{{ tag }}</option>
{% endfor %}
</select>
{% block folder_title %}
All categories
{% endblock%}

{% block actions_buttons %}
{% include "categories/dropdown_actions.html" %}
{% endblock actions_buttons %}

{% block system_list %}
{% for category in categories %}
<li class="list-group-item py-3">
<a class="d-block text-decoration-none" href="/folders/{{ category.name }}">
<div class="row">
<div class="col-9">
<div class="d-flex align-items-center">
<i class="fa fa-folder text-info me-3"></i>
<h5 class="mb-0">
{{ category.name }} <code class="ms-2"span><small>{{ category.path }}</small></code>
</h5>
</div>
</div>
</div>
</div>

<div class="row mt-4">
<div class="col-sm">
{% include "sources/magnet.html" %}
</div>

<div class="col-md-1 mt-3 mt-sm-0">
<div class="d-flex align-items-center h-100 justify-content-center">
<h2>OR</h2>
<div class="col-3">
<p class="mb-0 fst-italic text-end">
<i class="fa fa-chevron-right"></i>
</p>
</div>
</div>
</a>
</li>
{% endfor %}
{% endblock %}

<div class="col-sm mt-3 mt-sm-0">
{% include "sources/torrent.html" %}
</div>
</div>

<div class="text-center mt-4">
<input type="Submit" class="btn btn-success btn-lg" value="Next">
</div>
</form>

{% if categories.len() == 0 %}
<div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="false">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="staticBackdropLabel">Oops, you don't have any categories yet</h1>
</div>
<div class="modal-body">
{% include "categories/form.html" %}
</div>
</div>
</div>
</div>

<script>
window.addEventListener("load", (event) => {
const modal = new bootstrap.Modal('#staticBackdrop').show()
});
</script>
{% endif %}
</div>
{% endblock %}
57 changes: 57 additions & 0 deletions templates/layouts/file_system_base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{% extends "base.html" %}

{% block main %}
<div class="container">
<h1>File System</h1>

{% block alert_message %}{% endblock alert_message %}

{% if state.free_space.free_space_percent < 5 %}
<div class="alert alert-warning mt-4">
The disks are almost full : <span class="fw-bold">{{ state.free_space.free_space_gib }} GiB left</span>
</div>
{% endif %}

<div class="row align-items-center">
<div class="col-md-10">
<nav aria-label="breadcrumb">
<ol class="breadcrumb mb-0">
{% block breadcrumb %}{% endblock breadcrumb %}
</ol>
</nav>
</div>

<div class="col-md-2 text-end">
{% block actions_buttons %}{% endblock actions_buttons %}
</div>
</div>

<div class="card mt-4">
<div class="card-body">
<div class="p-4">
<div class="d-flex align-items-center mb-4">
<h4 class="mb-0">{% block folder_title %}{% endblock folder_title %}</h4> <div class="ms-4">{% block additional_buttons %}{% endblock additional_buttons %}</div>
</div>

<ul class="list-group">
{% block system_list %}{% endblock system_list %}
</ul>
</div>
</div>
</div>
</div>

<div class="modal fade" id="createSubFolder" tabindex="-1" aria-labelledby="createSubFolderLabel" aria-hidden="false">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="staticBackdropLabel">Create sub-folder</h1>
</div>
<div class="modal-body">
{% block content_folder_form %}{% endblock content_folder_form %}
</div>
</div>
</div>
</div>

{% endblock %}
2 changes: 1 addition & 1 deletion templates/menus/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<!-- </li> -->
</ul>
<span class="navbar-text">
<a class="btn btn-success text-white" href="/">
<a class="btn btn-success text-white" href="/upload">
<i class="fa fa-download me-2"></i>
Download new torrent
</a>
Expand Down
Loading