Skip to content

Commit

Permalink
categories
Browse files Browse the repository at this point in the history
  • Loading branch information
micielski committed Aug 20, 2024
1 parent 5ae6f90 commit 8998642
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 4 deletions.
6 changes: 6 additions & 0 deletions rm-config/defaults/categories.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Example category:
# [[category]]
# name = "Classical Music" # required
# prefix = "[M]" # optional, default: ""
# default_dir = "/mnt/Music/Classical" # optional, default: transmission's default
# color = "Green" # optional, default: "White"
2 changes: 1 addition & 1 deletion rm-config/defaults/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ free_space_refresh = 10
# Available fields:
# Id, Name, SizeWhenDone, Progress, Eta, DownloadRate, UploadRate, DownloadDir,
# Padding, UploadRatio, UploadedEver, AddedDate, ActivityDate, PeersConnected
# SmallStatus
# SmallStatus, Category
headers = ["Name", "SizeWhenDone", "Progress", "Eta", "DownloadRate", "UploadRate"]

[search_tab]
Expand Down
61 changes: 61 additions & 0 deletions rm-config/src/categories.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use std::{collections::HashMap, io::ErrorKind, path::PathBuf, sync::OnceLock};

use anyhow::{Context, Result};
use ratatui::style::Color;
use serde::Deserialize;

use crate::utils::{self, ConfigFetchingError};

#[derive(Deserialize)]
pub struct CategoriesConfig {
categories: Vec<Category>,
}

#[derive(Deserialize)]
pub struct Category {
pub name: String,
pub prefix: String,
pub color: Color,
pub default_dir: String,
}

impl CategoriesConfig {
pub(crate) const FILENAME: &'static str = "categories.toml";
pub const DEFAULT_CONFIG: &'static str = include_str!("../defaults/categories.toml");

pub(crate) fn init() -> Result<Self> {
match utils::fetch_config::<Self>(Self::FILENAME) {
Ok(config) => Ok(config),
Err(e) => match e {
ConfigFetchingError::Io(e) if e.kind() == ErrorKind::NotFound => {
let categories_config =
utils::put_config::<Self>(Self::DEFAULT_CONFIG, Self::FILENAME)?;
Ok(categories_config)
}
ConfigFetchingError::Toml(e) => Err(e).with_context(|| {
format!(
"Failed to parse config located at {:?}",
utils::get_config_path(Self::FILENAME)
)
}),
_ => anyhow::bail!(e),
},
}
}

pub(crate) fn path() -> &'static PathBuf {
static PATH: OnceLock<PathBuf> = OnceLock::new();
PATH.get_or_init(|| utils::get_config_path(Self::FILENAME))
}
}

impl CategoriesConfig {
pub fn to_hashmap(self) -> HashMap<String, Category> {
let mut hashmap = HashMap::new();
for category in self.categories {
hashmap.insert(category.name.clone(), category);
}

hashmap
}
}
9 changes: 8 additions & 1 deletion rm-config/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
pub mod categories;
pub mod keymap;
pub mod main_config;
mod utils;

use std::{path::PathBuf, sync::LazyLock};
use std::{collections::HashMap, path::PathBuf, sync::LazyLock};

use anyhow::Result;
use categories::{CategoriesConfig, Category};
use keymap::KeymapConfig;
use main_config::MainConfig;

Expand All @@ -22,22 +24,26 @@ pub struct Config {
pub search_tab: main_config::SearchTab,
pub icons: main_config::Icons,
pub keybindings: KeymapConfig,
pub categories: HashMap<String, Category>,
pub directories: Directories,
}

pub struct Directories {
pub main_path: &'static PathBuf,
pub keymap_path: &'static PathBuf,
pub categories_path: &'static PathBuf,
}

impl Config {
fn init() -> Result<Self> {
let main_config = MainConfig::init()?;
let keybindings = KeymapConfig::init()?;
let categories = CategoriesConfig::init()?;

let directories = Directories {
main_path: MainConfig::path(),
keymap_path: KeymapConfig::path(),
categories_path: CategoriesConfig::path(),
};

Ok(Self {
Expand All @@ -47,6 +53,7 @@ impl Config {
search_tab: main_config.search_tab,
icons: main_config.icons,
keybindings: keybindings.clone(),
categories: categories.to_hashmap(),
directories,
})
}
Expand Down
1 change: 1 addition & 0 deletions rm-main/src/transmission/fetchers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ pub async fn torrents(ctx: app::Ctx) {
TorrentGetField::PeersConnected,
TorrentGetField::Error,
TorrentGetField::ErrorString,
TorrentGetField::Labels,
];
let (torrents_tx, torrents_rx) = oneshot::channel();
ctx.send_torrent_action(TorrentAction::GetTorrents(fields, torrents_tx));
Expand Down
7 changes: 6 additions & 1 deletion rm-main/src/tui/components/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ impl<T: Clone> GenericTable<T> {
}

pub fn select_last(&mut self) {
self.state.borrow_mut().select_last();
if self.items.is_empty() {
return;
}

let mut state = self.state.borrow_mut();
state.select(Some(self.items.len() - 1));
}
}
14 changes: 14 additions & 0 deletions rm-main/src/tui/tabs/torrents/rustmission_torrent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub struct RustmissionTorrent {
pub activity_date: NaiveDateTime,
pub added_date: NaiveDateTime,
pub peers_connected: i64,
pub categories: Vec<String>,
pub error: Option<String>,
}

Expand Down Expand Up @@ -176,6 +177,16 @@ impl RustmissionTorrent {
}
}
}
Header::Category => match self.categories.get(0) {
Some(category) => {
if let Some(config_category) = CONFIG.categories.get(category) {
Cell::from(category.as_str()).fg(config_category.color)
} else {
Cell::from(category.as_str())
}
}
None => Cell::default(),
},
}
}

Expand Down Expand Up @@ -271,6 +282,8 @@ impl From<Torrent> for RustmissionTorrent {
}
};

let categories = t.labels.unwrap();

Self {
torrent_name,
size_when_done,
Expand All @@ -287,6 +300,7 @@ impl From<Torrent> for RustmissionTorrent {
activity_date,
added_date,
peers_connected,
categories,
error,
}
}
Expand Down
5 changes: 4 additions & 1 deletion rm-shared/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Hash, PartialEq, Eq, Clone, Copy)]
pub enum Header {
Id,
Name,
SizeWhenDone,
Progress,
Expand All @@ -13,11 +14,11 @@ pub enum Header {
Padding,
UploadRatio,
UploadedEver,
Id,
ActivityDate,
AddedDate,
PeersConnected,
SmallStatus,
Category,
}

impl Header {
Expand All @@ -38,6 +39,7 @@ impl Header {
Self::AddedDate => Constraint::Length(12),
Self::PeersConnected => Constraint::Length(6),
Self::SmallStatus => Constraint::Length(1),
Self::Category => Constraint::Max(15),
}
}

Expand All @@ -58,6 +60,7 @@ impl Header {
Self::AddedDate => "Added",
Self::PeersConnected => "Peers",
Self::SmallStatus => "",
Self::Category => "Category",
}
}
}

0 comments on commit 8998642

Please sign in to comment.