ui: add manual_refresh, refresh_command settings

manual_refresh Ar boolean
  (optional) if true, do not monitor account for changes (shortcut listing.refresh)
  refresh_command Ar String
  (optional) command to execute when manually refreshing (shortcut listing.refresh)
async
Manos Pitsidianakis 2020-01-08 21:41:57 +02:00
parent 5e912db461
commit 86d8419ce7
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
6 changed files with 111 additions and 10 deletions

View File

@ -53,7 +53,7 @@ is not a comment:
The accepted regular expression is
.Li ^\es*include\es*\&\\&\e"(\e\e.|[^\e"])+\e"\es*$
.Sh SECTIONS
The top level sections of the config are accounts, shortcuts, notifications, pager, composing, pgp, terminal.
The top level sections of the config are accounts, shortcuts, notifications, pager, listing, composing, pgp, terminal.
.Pp
.Sy example configuration
@ -138,6 +138,12 @@ plain:shows one row per mail, regardless of threading
.It Ic read_only Ar boolean
attempt to not make any changes to this account.
.Pq Em false
.It Ic manual_refresh Ar boolean
(optional) if true, do not monitor account for changes (shortcut listing.refresh)
.Pq Em false
.It Ic refresh_command Ar String
(optional) command to execute when manually refreshing (shortcut listing.refresh)
.Pq Em None
.It Ic cache_type Ar String
(optional) choose which cache backend to use. Available options are 'none' and 'sqlite3'
.Pq Em "sqlite3"
@ -351,6 +357,14 @@ Go to next account.
Start new mail draft in new tab
.\" default value
.Pq Em m
.It Ic set_seen
Set thread as seen.
.\" default value
.Pq Em n
.It Ic refresh
Manually request a folder refresh.
.\" default value
.Pq Em F5
.It Ic search
Search within list of e-mails.
.\" default value
@ -563,6 +577,21 @@ enable freedesktop-spec notifications. this is usually what you want
.\" default value
.Pq Em 80
.El
.Sh LISTING
.Bl -tag -width 36n
.It Ic context_lines Ar num
(optional) number of context lines when going to next page. (Unimplemented)
.\" default value
.Pq Em 0
.It Ic datetime_fmt Ar String
(optional) datetime formatting passed verbatim to strftime(3).
.\" default value
.Pq Em \&%Y-\&%m-\&%d \&%T
.It Ic recent_dates Ar Boolean
(optional) Show recent dates as `X {minutes,hours,days} ago`, up to 7 days.
.\" default value
.Pq Em true
.El
.Sh TAGS
.Bl -tag -width 36n
.It Ic colours Ar hash table String[Color]

View File

@ -591,7 +591,7 @@ impl CompactListing {
subject.truncate_at_boundary(150);
if thread_node.len() > 0 {
EntryStrings {
date: DateString(ConversationsListing::format_date(thread_node)),
date: DateString(ConversationsListing::format_date(context, thread_node)),
subject: SubjectString(format!("{} ({})", subject, thread_node.len(),)),
flag: FlagString(format!(
"{}{}",
@ -603,7 +603,7 @@ impl CompactListing {
}
} else {
EntryStrings {
date: DateString(ConversationsListing::format_date(thread_node)),
date: DateString(ConversationsListing::format_date(context, thread_node)),
subject: SubjectString(subject),
flag: FlagString(format!(
"{}{}",

View File

@ -562,7 +562,7 @@ impl ConversationsListing {
subject.truncate_at_boundary(150);
if thread_node.len() > 0 {
EntryStrings {
date: DateString(ConversationsListing::format_date(thread_node)),
date: DateString(ConversationsListing::format_date(context, thread_node)),
subject: SubjectString(format!("{} ({})", subject, thread_node.len(),)),
flag: FlagString(format!(
"{}{}",
@ -574,7 +574,7 @@ impl ConversationsListing {
}
} else {
EntryStrings {
date: DateString(ConversationsListing::format_date(thread_node)),
date: DateString(ConversationsListing::format_date(context, thread_node)),
subject: SubjectString(subject),
flag: FlagString(format!(
"{}{}",
@ -890,28 +890,37 @@ impl ConversationsListing {
}
}
pub(super) fn format_date(thread_node: &ThreadNode) -> String {
pub(super) fn format_date(context: &Context, thread_node: &ThreadNode) -> String {
let d = std::time::UNIX_EPOCH + std::time::Duration::from_secs(thread_node.date());
let now: std::time::Duration = std::time::SystemTime::now()
.duration_since(d)
.unwrap_or_else(|_| std::time::Duration::new(std::u64::MAX, 0));
match now.as_secs() {
n if n < 60 * 60 => format!(
n if context.settings.listing.recent_dates && n < 60 * 60 => format!(
"{} minute{} ago",
n / (60),
if n / 60 == 1 { "" } else { "s" }
),
n if n < 24 * 60 * 60 => format!(
n if context.settings.listing.recent_dates && n < 24 * 60 * 60 => format!(
"{} hour{} ago",
n / (60 * 60),
if n / (60 * 60) == 1 { "" } else { "s" }
),
n if n < 7 * 24 * 60 * 60 => format!(
n if context.settings.listing.recent_dates && n < 7 * 24 * 60 * 60 => format!(
"{} day{} ago",
n / (24 * 60 * 60),
if n / (24 * 60 * 60) == 1 { "" } else { "s" }
),
_ => melib::datetime::timestamp_to_string(thread_node.date(), Some("%Y-%m-%d %T")),
_ => melib::datetime::timestamp_to_string(
thread_node.date(),
context
.settings
.listing
.datetime_fmt
.as_ref()
.map(String::as_str)
.or(Some("%Y-%m-%d %T")),
),
}
}

View File

@ -31,6 +31,7 @@ pub mod pgp;
pub mod tags;
#[macro_use]
pub mod shortcuts;
mod listing;
pub mod terminal;
pub mod accounts;
@ -41,6 +42,7 @@ pub use self::shortcuts::*;
pub use self::tags::*;
use self::default_vals::*;
use self::listing::ListingSettings;
use self::notifications::NotificationsSettings;
use self::terminal::TerminalSettings;
use crate::pager::PagerSettings;
@ -68,6 +70,7 @@ macro_rules! split_command {
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct MailUIConf {
pub pager: Option<PagerSettings>,
pub listing: Option<ListingSettings>,
pub notifications: Option<NotificationsSettings>,
pub shortcuts: Option<Shortcuts>,
pub composing: Option<ComposingSettings>,
@ -114,6 +117,8 @@ pub struct FileAccount {
cache_type: CacheType,
#[serde(default)]
pub manual_refresh: bool,
#[serde(default = "none")]
pub refresh_command: Option<String>,
#[serde(flatten)]
#[serde(deserialize_with = "extra_settings")]
pub extra: HashMap<String, String>, /* use custom deserializer to convert any given value (eg bool, number, etc) to string */
@ -230,6 +235,8 @@ pub struct FileSettings {
#[serde(default)]
pager: PagerSettings,
#[serde(default)]
listing: ListingSettings,
#[serde(default)]
notifications: NotificationsSettings,
#[serde(default)]
shortcuts: Shortcuts,
@ -267,6 +274,7 @@ impl AccountConf {
pub struct Settings {
pub accounts: HashMap<String, AccountConf>,
pub pager: PagerSettings,
pub listing: ListingSettings,
pub notifications: NotificationsSettings,
pub shortcuts: Shortcuts,
pub tags: TagsSettings,
@ -359,6 +367,7 @@ impl FileSettings {
folders,
extra,
manual_refresh,
refresh_command: _,
index_style: _,
cache_type: _,
} = acc;
@ -401,6 +410,7 @@ impl Settings {
Ok(Settings {
accounts: s,
pager: fs.pager,
listing: fs.listing,
notifications: fs.notifications,
shortcuts: fs.shortcuts,
tags: fs.tags,

View File

@ -723,6 +723,18 @@ impl Account {
None
}
pub fn refresh(&mut self, folder_hash: FolderHash) -> Result<()> {
if let Some(ref refresh_command) = self.settings.conf().refresh_command {
let parts = crate::split_command!(refresh_command);
let (cmd, args) = (parts[0], &parts[1..]);
std::process::Command::new(cmd)
.args(args)
.stdin(std::process::Stdio::null())
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::piped())
.spawn()?;
return Ok(());
}
let sender_ = self.sender.clone();
let r = RefreshEventConsumer::new(Box::new(move |r| {
sender_.send(ThreadEvent::from(r)).unwrap();

View File

@ -0,0 +1,41 @@
/*
* meli - listing conf module
*
* Copyright 2020 Manos Pitsidianakis
*
* This file is part of meli.
*
* meli is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* meli is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
use super::default_vals::*;
/// Settings for mail listings
#[derive(Debug, Deserialize, Clone, Default, Serialize)]
pub struct ListingSettings {
/// Number of context lines when going to next page.
/// Default: 0
#[serde(default = "zero_val")]
pub context_lines: usize,
/// Datetime formatting passed verbatim to strftime(3).
/// Default: %Y-%m-%d %T
#[serde(default = "none")]
pub datetime_fmt: Option<String>,
/// Show recent dates as `X {minutes,hours,days} ago`, up to 7 days.
/// Default: true
#[serde(default = "true_val")]
pub recent_dates: bool,
}