Skip to content

Commit 7536668

Browse files
committed
feat: Display pending torrents in category/folders
1 parent 24defbf commit 7536668

6 files changed

Lines changed: 86 additions & 1 deletion

File tree

src/database/torrent.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ pub struct TorrentOperator {
6262
}
6363

6464
impl TorrentOperator {
65+
pub fn new(state: AppState, user: Option<User>) -> Self {
66+
Self { state, user }
67+
}
68+
6569
pub fn db(&self) -> DatabaseOperator {
6670
DatabaseOperator {
6771
state: self.state.clone(),
@@ -97,6 +101,35 @@ impl TorrentOperator {
97101
.context(DBSnafu)
98102
}
99103

104+
/// List torrents in a specific category (without recursing)
105+
///
106+
/// Should not fail, unless SQLite was corrupted for some reason.
107+
pub async fn list_for_category(&self, category_id: i32) -> Result<Vec<Model>, TorrentError> {
108+
// TODO: optimization
109+
Ok(self
110+
.list()
111+
.await?
112+
.into_iter()
113+
.filter(|x| x.category_id == category_id && x.content_folder_id.is_none())
114+
.collect())
115+
}
116+
117+
/// List torrents in a specific content_folder (without recursing)
118+
///
119+
/// Should not fail, unless SQLite was corrupted for some reason.
120+
pub async fn list_for_content_folder(
121+
&self,
122+
content_folder_id: i32,
123+
) -> Result<Vec<Model>, TorrentError> {
124+
// TODO: optimization
125+
Ok(self
126+
.list()
127+
.await?
128+
.into_iter()
129+
.filter(|x| x.content_folder_id == Some(content_folder_id))
130+
.collect())
131+
}
132+
100133
/// Count magnets
101134
///
102135
/// Should not fail, unless SQLite was corrupted for some reason.

src/extractors/category_request.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use snafu::prelude::*;
44

55
use crate::database::category::{self, CategoryOperator};
66
use crate::database::content_folder::PathBreadcrumb;
7+
use crate::database::torrent::{self, TorrentOperator};
78
use crate::filesystem::FileSystemEntry;
89
use crate::state::{AppState, error::*};
910

@@ -34,6 +35,7 @@ pub struct CategoryRequest {
3435
pub category: category::Model,
3536
pub breadcrumbs: Vec<PathBreadcrumb>,
3637
pub children: Vec<FileSystemEntry>,
38+
pub torrents: Vec<torrent::Model>,
3739
}
3840

3941
impl FromRequestParts<AppState> for CategoryRequest {
@@ -66,10 +68,16 @@ impl FromRequestParts<AppState> for CategoryRequest {
6668

6769
let breadcrumbs = PathBreadcrumb::for_filesystem_path(category.name.as_str());
6870

71+
let torrents = TorrentOperator::new(app_state.clone(), None)
72+
.list_for_category(category.id)
73+
.await
74+
.context(TorrentUploadSnafu)?;
75+
6976
Ok(Self {
7077
category,
7178
children,
7279
breadcrumbs,
80+
torrents,
7381
})
7482
}
7583
}

src/extractors/folder_request.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use snafu::prelude::*;
44

55
use crate::database::category::{self, CategoryOperator};
66
use crate::database::content_folder::{self, ContentFolderOperator, PathBreadcrumb};
7+
use crate::database::torrent::{self, TorrentOperator};
78
use crate::filesystem::FileSystemEntry;
89
use crate::state::AppState;
910
use crate::state::error::*;
@@ -14,6 +15,7 @@ pub struct FolderRequest {
1415
pub folder: content_folder::Model,
1516
pub children: Vec<FileSystemEntry>,
1617
pub breadcrumbs: Vec<PathBreadcrumb>,
18+
pub torrents: Vec<torrent::Model>,
1719
}
1820

1921
impl FromRequestParts<AppState> for FolderRequest {
@@ -34,6 +36,7 @@ impl FromRequestParts<AppState> for FolderRequest {
3436
// Read-only operators: no need to extract the current user
3537
let category_operator = CategoryOperator::new(app_state.clone(), None);
3638
let content_folder_operator = ContentFolderOperator::new(app_state.clone(), None);
39+
let torrent_operator = TorrentOperator::new(app_state.clone(), None);
3740

3841
// get current content folders with Path
3942
let current_content_folder = content_folder_operator
@@ -60,11 +63,17 @@ impl FromRequestParts<AppState> for FolderRequest {
6063
category.name, current_content_folder.path
6164
));
6265

66+
let torrents = torrent_operator
67+
.list_for_content_folder(current_content_folder.id)
68+
.await
69+
.context(TorrentUploadSnafu)?;
70+
6371
Ok(Self {
6472
category,
6573
folder: current_content_folder,
6674
children,
6775
breadcrumbs,
76+
torrents,
6877
})
6978
}
7079
}

src/routes/category.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize};
77

88
use crate::database::category;
99
use crate::database::content_folder::PathBreadcrumb;
10+
use crate::database::torrent;
1011
use crate::extractors::category_request::{CategoriesRequest, CategoryRequest};
1112
use crate::filesystem::FileSystemEntry;
1213
use crate::routes::content_folder::ContentFolderForm;
@@ -92,6 +93,8 @@ pub struct CategoryShowTemplate {
9293
pub flash: Option<OperationStatus>,
9394
/// Breadcrumbs navigation
9495
pub breadcrumbs: Vec<PathBreadcrumb>,
96+
/// Torrents in this category
97+
pub torrents: Vec<torrent::Model>,
9598
}
9699

97100
impl CategoryShowTemplate {
@@ -100,6 +103,7 @@ impl CategoryShowTemplate {
100103
breadcrumbs,
101104
category,
102105
children,
106+
torrents,
103107
} = category;
104108

105109
Self {
@@ -108,6 +112,7 @@ impl CategoryShowTemplate {
108112
children,
109113
flash: None,
110114
state: context,
115+
torrents,
111116
}
112117
}
113118
}

src/routes/content_folder.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use axum_extra::extract::CookieJar;
55
use serde::{Deserialize, Serialize};
66

77
use crate::database::content_folder::PathBreadcrumb;
8-
use crate::database::{category, content_folder};
8+
use crate::database::{category, content_folder, torrent};
99
use crate::extractors::folder_request::FolderRequest;
1010
use crate::filesystem::FileSystemEntry;
1111
use crate::state::AppStateContext;
@@ -35,6 +35,8 @@ pub struct ContentFolderShowTemplate {
3535
pub breadcrumbs: Vec<PathBreadcrumb>,
3636
/// Operation status for UI confirmation (Cookie)
3737
pub flash: Option<OperationStatus>,
38+
/// Related torrents in this folder
39+
pub torrents: Vec<torrent::Model>,
3840
}
3941

4042
impl ContentFolderShowTemplate {
@@ -44,6 +46,7 @@ impl ContentFolderShowTemplate {
4446
category,
4547
children,
4648
folder,
49+
torrents,
4750
} = folder;
4851

4952
Self {
@@ -53,6 +56,7 @@ impl ContentFolderShowTemplate {
5356
flash: None,
5457
folder,
5558
state: context,
59+
torrents,
5660
}
5761
}
5862
}

templates/layouts/file_system_base.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,32 @@ <h1>File System</h1>
4242
</div>
4343
</div>
4444

45+
{# torrents is not defined on the homepage (category list) #}
46+
{% if torrents is defined && torrents.len() > 0 %}
47+
<div class="card mt-4">
48+
<div class="card-body">
49+
<div class="p-4">
50+
<div class="d-flex align-items-center mb-4">
51+
<h4 class="mb-0">{{ torrents.len() }} torrents waiting for confirmation in this folder</h4>
52+
</div>
53+
</div>
54+
<ul class="list-group">
55+
{% for torrent in torrents %}
56+
<li>
57+
<span>{{ torrent.name }} will create the following folders/files in this folder:</span>
58+
{# TODO: file tree in hightorrent #}
59+
<ul>
60+
{% for file in torrent.file.decoded.files().unwrap() %}
61+
<li>({{ file.size | filesizeformat }}) {{ file.path.to_str().unwrap() }}</li>
62+
{% endfor %}
63+
</ul>
64+
</li>
65+
{% endfor %}
66+
</ul>
67+
</div>
68+
</div>
69+
{% endif %}
70+
4571
<div class="card mt-4">
4672
<div class="card-body">
4773
<div class="p-4">

0 commit comments

Comments
 (0)