Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

configurable headers #48 #55

Merged
merged 13 commits into from
Jul 8, 2024
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions rm-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ url.workspace = true
ratatui.workspace = true
crossterm.workspace = true
thiserror.workspace = true
transmission-rpc.workspace = true
16 changes: 11 additions & 5 deletions rm-config/defaults/config.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[general]
[General]
# Whether to hide empty columns or not
aidanaden marked this conversation as resolved.
Show resolved Hide resolved
auto_hide = false

Expand All @@ -17,11 +17,17 @@ headers_hide = false
[connection]
url = "http://CHANGE_ME:9091/transmission/rpc" # REQUIRED!

# Refresh timings (in seconds)
torrents_refresh = 5
stats_refresh = 5
free_space_refresh = 10

# If you need username and password to authenticate:
# username = "CHANGE_ME"
# password = "CHANGE_ME"

# Refresh timings (in seconds)
torrents_refresh = 5
stats_refresh = 10
free_space_refresh = 10

[torrents_tab]
# Available fields:
# Name, SizeWhenDone, Progress, DownloadRate, UploadRate, DownloadDir
headers = ["Name", "SizeWhenDone", "Progress", "DownloadRate", "UploadRate"]
4 changes: 3 additions & 1 deletion rm-config/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod keymap;
mod main_config;
pub mod main_config;
mod utils;

use std::path::PathBuf;
Expand All @@ -11,6 +11,7 @@ use main_config::MainConfig;
pub struct Config {
pub general: main_config::General,
pub connection: main_config::Connection,
pub torrents_tab: main_config::TorrentsTab,
pub keybindings: KeymapConfig,
pub directories: Directories,
}
Expand All @@ -33,6 +34,7 @@ impl Config {
Ok(Self {
general: main_config.general,
connection: main_config.connection,
torrents_tab: main_config.torrents_tab,
keybindings: keybindings.clone(),
directories,
})
Expand Down
88 changes: 75 additions & 13 deletions rm-config/src/main_config.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
use std::{path::PathBuf, sync::OnceLock};
use std::{io::ErrorKind, path::PathBuf, sync::OnceLock};

use anyhow::Result;
use ratatui::style::Color;
use ratatui::{layout::Constraint, style::Color};
use serde::{Deserialize, Serialize};
use url::Url;

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

#[derive(Serialize, Deserialize)]
#[derive(Deserialize)]
pub struct MainConfig {
pub general: General,
pub connection: Connection,
#[serde(default)]
pub torrents_tab: TorrentsTab,
}

#[derive(Debug, Serialize, Deserialize)]
#[derive(Deserialize)]
pub struct General {
#[serde(default)]
pub auto_hide: bool,
Expand All @@ -33,7 +35,7 @@ fn default_beginner_mode() -> bool {
true
}

#[derive(Debug, Serialize, Deserialize)]
#[derive(Deserialize)]
pub struct Connection {
pub username: Option<String>,
pub password: Option<String>,
Expand All @@ -50,19 +52,79 @@ fn default_refresh() -> u64 {
5
}

#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub enum Header {
Name,
SizeWhenDone,
Progress,
Eta,
DownloadRate,
UploadRate,
DownloadDir,
}

impl Header {
pub fn default_constraint(&self) -> Constraint {
match self {
Header::Name => Constraint::Max(70),
Header::SizeWhenDone => Constraint::Length(12),
Header::Progress => Constraint::Length(12),
Header::Eta => Constraint::Length(12),
Header::DownloadRate => Constraint::Length(12),
Header::UploadRate => Constraint::Length(12),
Header::DownloadDir => Constraint::Max(70),
}
aidanaden marked this conversation as resolved.
Show resolved Hide resolved
}

pub fn header_name(&self) -> &'static str {
match self {
Header::Name => "Name",
Header::SizeWhenDone => "Size",
Header::Progress => "Progress",
Header::Eta => "ETA",
Header::DownloadRate => "Download",
Header::UploadRate => "Upload",
Header::DownloadDir => "Directory",
}
}
}

#[derive(Deserialize)]
pub struct TorrentsTab {
pub headers: Vec<Header>,
}

impl Default for TorrentsTab {
fn default() -> Self {
Self {
headers: vec![
Header::Name,
Header::SizeWhenDone,
Header::Progress,
Header::Eta,
Header::DownloadRate,
Header::UploadRate,
],
}
}
}

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

pub(crate) fn init() -> Result<Self> {
let Ok(config) = utils::fetch_config(Self::FILENAME) else {
put_config(Self::DEFAULT_CONFIG, Self::FILENAME)?;
// TODO: check if the user really changed the config.
println!("Update {:?} and start rustmission again", Self::path());
std::process::exit(0);
match utils::fetch_config::<Self>(Self::FILENAME) {
Ok(config) => return Ok(config),
Err(e) => match e {
utils::ConfigFetchingError::Io(e) if e.kind() == ErrorKind::NotFound => {
utils::put_config::<Self>(Self::DEFAULT_CONFIG, Self::FILENAME)?;
println!("Update {:?} and start rustmission again", Self::path());
std::process::exit(0);
}
_ => anyhow::bail!(e),
},
};

Ok(config)
}

pub(crate) fn path() -> &'static PathBuf {
Expand Down
4 changes: 2 additions & 2 deletions rm-config/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ pub fn fetch_config<T: DeserializeOwned>(config_name: &str) -> Result<T, ConfigF
pub fn put_config<T: DeserializeOwned>(
content: &'static str,
filename: &str,
) -> Result<T, io::Error> {
) -> Result<T, ConfigFetchingError> {
let config_path = get_config_path(filename);
let mut config_file = File::create(config_path)?;
config_file.write_all(content.as_bytes())?;
Ok(toml::from_str(content).expect("default configs are correct"))
Ok(toml::from_str(content)?)
}
6 changes: 2 additions & 4 deletions rm-main/src/ui/tabs/torrents/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,10 @@ impl TorrentsTab {
.accent_color);

let table_widget = {
let table = Table::new(torrent_rows, table_manager_lock.widths)
let table = Table::new(torrent_rows, &table_manager_lock.widths)
.highlight_style(highlight_table_style);
if !self.ctx.config.general.headers_hide {
table.header(Row::new(
table_manager_lock.header().iter().map(|s| s.as_str()),
))
table.header(Row::new(table_manager_lock.header().iter().cloned()))
} else {
table
}
Expand Down
37 changes: 21 additions & 16 deletions rm-main/src/ui/tabs/torrents/rustmission_torrent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use ratatui::{
text::{Line, Span},
widgets::Row,
};
use rm_config::main_config::Header;
use transmission_rpc::types::{Id, Torrent, TorrentStatus};

use crate::utils::{
Expand All @@ -24,18 +25,25 @@ pub struct RustmissionTorrent {
}

impl RustmissionTorrent {
pub fn to_row(&self) -> ratatui::widgets::Row {
Row::new([
Line::from(self.torrent_name.as_str()),
Line::from(""),
Line::from(self.size_when_done.as_str()),
Line::from(self.progress.as_str()),
Line::from(self.eta_secs.as_str()),
Line::from(download_speed_format(&self.download_speed)),
Line::from(upload_speed_format(&self.upload_speed)),
Line::from(self.download_dir.as_str()),
])
.style(self.style)
pub fn to_row(&self, headers: &Vec<Header>) -> ratatui::widgets::Row {
let mut cells = vec![];
for header in headers {
match header {
Header::Name => cells.push(Line::from(self.torrent_name.as_str())),
Header::SizeWhenDone => cells.push(Line::from(self.size_when_done.as_str())),
Header::Progress => cells.push(Line::from(self.progress.as_str())),
Header::Eta => cells.push(Line::from(self.eta_secs.as_str())),
Header::DownloadRate => {
cells.push(Line::from(download_speed_format(&self.download_speed)))
}
Header::UploadRate => {
cells.push(Line::from(upload_speed_format(&self.upload_speed)))
}
Header::DownloadDir => cells.push(Line::from(self.download_dir.as_str())),
};
micielski marked this conversation as resolved.
Show resolved Hide resolved
}

Row::new(cells).style(self.style)
}

pub fn to_row_with_higlighted_indices(
Expand Down Expand Up @@ -116,10 +124,7 @@ impl From<&Torrent> for RustmissionTorrent {
_ => Style::default(),
};

let download_dir = t
.download_dir
.clone()
.expect("torrent download directory requested");
let download_dir = t.download_dir.clone().expect("field requested");

Self {
torrent_name,
Expand Down
Loading
Loading