mirror of
https://github.com/soywod/himalaya.git
synced 2024-11-25 04:20:22 +00:00
fix flags case sensitivity
This commit is contained in:
parent
0ab652b4b6
commit
3631ca714b
13 changed files with 194 additions and 17 deletions
|
@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
- Fixed config deserialization issue with `email-hooks` and
|
- Fixed config deserialization issue with `email-hooks` and
|
||||||
`email-reading-format`.
|
`email-reading-format`.
|
||||||
|
- Fixed flags case sensitivity.
|
||||||
|
|
||||||
## [0.7.1] - 2023-02-14
|
## [0.7.1] - 2023-02-14
|
||||||
|
|
||||||
|
|
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -775,6 +775,7 @@ version = "0.7.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"atty",
|
"atty",
|
||||||
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
"clap_mangen",
|
"clap_mangen",
|
||||||
|
@ -803,7 +804,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "himalaya-lib"
|
name = "himalaya-lib"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://git.sr.ht/~soywod/himalaya-lib?branch=develop#8c538689c9d3098f8e69493791ccbbe52eb9af58"
|
source = "git+https://git.sr.ht/~soywod/himalaya-lib?branch=develop#26d3b9e74c978f6dc94689bff809d48fe5ba4c85"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ammonia",
|
"ammonia",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -827,7 +828,6 @@ dependencies = [
|
||||||
"regex",
|
"regex",
|
||||||
"rfc2047-decoder",
|
"rfc2047-decoder",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"serde",
|
|
||||||
"shellexpand",
|
"shellexpand",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tree_magic",
|
"tree_magic",
|
||||||
|
|
|
@ -27,6 +27,7 @@ tempfile = "3.3"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
atty = "0.2"
|
atty = "0.2"
|
||||||
|
chrono = "0.4.23"
|
||||||
clap = "4.0"
|
clap = "4.0"
|
||||||
clap_complete = "4.0"
|
clap_complete = "4.0"
|
||||||
clap_mangen = "0.2"
|
clap_mangen = "0.2"
|
||||||
|
|
|
@ -14,6 +14,7 @@ use uuid::Uuid;
|
||||||
use crate::{
|
use crate::{
|
||||||
printer::{PrintTableOpts, Printer},
|
printer::{PrintTableOpts, Printer},
|
||||||
ui::editor,
|
ui::editor,
|
||||||
|
Envelopes,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn attachments<P: Printer, B: Backend + ?Sized>(
|
pub fn attachments<P: Printer, B: Backend + ?Sized>(
|
||||||
|
@ -132,10 +133,10 @@ pub fn list<P: Printer, B: Backend + ?Sized>(
|
||||||
let folder = config.folder_alias(folder)?;
|
let folder = config.folder_alias(folder)?;
|
||||||
let page_size = page_size.unwrap_or(config.email_listing_page_size());
|
let page_size = page_size.unwrap_or(config.email_listing_page_size());
|
||||||
debug!("page size: {}", page_size);
|
debug!("page size: {}", page_size);
|
||||||
let msgs = backend.list_envelopes(&folder, page_size, page)?;
|
let envelopes: Envelopes = backend.list_envelopes(&folder, page_size, page)?.into();
|
||||||
trace!("envelopes: {:?}", msgs);
|
trace!("envelopes: {:?}", envelopes);
|
||||||
printer.print_table(
|
printer.print_table(
|
||||||
Box::new(msgs),
|
Box::new(envelopes),
|
||||||
PrintTableOpts {
|
PrintTableOpts {
|
||||||
format: &config.email_reading_format,
|
format: &config.email_reading_format,
|
||||||
max_width,
|
max_width,
|
||||||
|
@ -291,7 +292,9 @@ pub fn search<P: Printer, B: Backend + ?Sized>(
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let folder = config.folder_alias(folder)?;
|
let folder = config.folder_alias(folder)?;
|
||||||
let page_size = page_size.unwrap_or(config.email_listing_page_size());
|
let page_size = page_size.unwrap_or(config.email_listing_page_size());
|
||||||
let envelopes = backend.search_envelopes(&folder, &query, "", page_size, page)?;
|
let envelopes: Envelopes = backend
|
||||||
|
.search_envelopes(&folder, &query, "", page_size, page)?
|
||||||
|
.into();
|
||||||
let opts = PrintTableOpts {
|
let opts = PrintTableOpts {
|
||||||
format: &config.email_reading_format,
|
format: &config.email_reading_format,
|
||||||
max_width,
|
max_width,
|
||||||
|
@ -313,7 +316,9 @@ pub fn sort<P: Printer, B: Backend + ?Sized>(
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let folder = config.folder_alias(folder)?;
|
let folder = config.folder_alias(folder)?;
|
||||||
let page_size = page_size.unwrap_or(config.email_listing_page_size());
|
let page_size = page_size.unwrap_or(config.email_listing_page_size());
|
||||||
let envelopes = backend.search_envelopes(&folder, &query, &sort, page_size, page)?;
|
let envelopes: Envelopes = backend
|
||||||
|
.search_envelopes(&folder, &query, &sort, page_size, page)?
|
||||||
|
.into();
|
||||||
let opts = PrintTableOpts {
|
let opts = PrintTableOpts {
|
||||||
format: &config.email_reading_format,
|
format: &config.email_reading_format,
|
||||||
max_width,
|
max_width,
|
||||||
|
|
|
@ -1,6 +1,45 @@
|
||||||
use himalaya_lib::{Envelope, Flag};
|
use chrono::{DateTime, Local};
|
||||||
|
use serde::{Serialize, Serializer};
|
||||||
|
|
||||||
use crate::ui::{Cell, Row, Table};
|
use crate::{
|
||||||
|
ui::{Cell, Row, Table},
|
||||||
|
Flag, Flags,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn date<S: Serializer>(date: &DateTime<Local>, s: S) -> Result<S::Ok, S::Error> {
|
||||||
|
s.serialize_str(&date.to_rfc3339())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, Serialize)]
|
||||||
|
pub struct Mailbox {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub addr: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, Serialize)]
|
||||||
|
pub struct Envelope {
|
||||||
|
pub id: String,
|
||||||
|
pub flags: Flags,
|
||||||
|
pub subject: String,
|
||||||
|
pub from: Mailbox,
|
||||||
|
#[serde(serialize_with = "date")]
|
||||||
|
pub date: DateTime<Local>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&himalaya_lib::Envelope> for Envelope {
|
||||||
|
fn from(envelope: &himalaya_lib::Envelope) -> Self {
|
||||||
|
Envelope {
|
||||||
|
id: envelope.id.clone(),
|
||||||
|
flags: envelope.flags.clone().into(),
|
||||||
|
subject: envelope.subject.clone(),
|
||||||
|
from: Mailbox {
|
||||||
|
name: envelope.from.name.clone(),
|
||||||
|
addr: envelope.from.addr.clone(),
|
||||||
|
},
|
||||||
|
date: envelope.date.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Table for Envelope {
|
impl Table for Envelope {
|
||||||
fn head() -> Row {
|
fn head() -> Row {
|
||||||
|
@ -14,15 +53,29 @@ impl Table for Envelope {
|
||||||
|
|
||||||
fn row(&self) -> Row {
|
fn row(&self) -> Row {
|
||||||
let id = self.id.to_string();
|
let id = self.id.to_string();
|
||||||
let flags = self.flags.to_symbols_string();
|
|
||||||
let unseen = !self.flags.contains(&Flag::Seen);
|
let unseen = !self.flags.contains(&Flag::Seen);
|
||||||
|
let flags = {
|
||||||
|
let mut flags = String::new();
|
||||||
|
flags.push_str(if !unseen { " " } else { "✷" });
|
||||||
|
flags.push_str(if self.flags.contains(&Flag::Answered) {
|
||||||
|
"↵"
|
||||||
|
} else {
|
||||||
|
" "
|
||||||
|
});
|
||||||
|
flags.push_str(if self.flags.contains(&Flag::Flagged) {
|
||||||
|
"⚑"
|
||||||
|
} else {
|
||||||
|
" "
|
||||||
|
});
|
||||||
|
flags
|
||||||
|
};
|
||||||
let subject = &self.subject;
|
let subject = &self.subject;
|
||||||
let sender = if let Some(name) = &self.from.name {
|
let sender = if let Some(name) = &self.from.name {
|
||||||
name
|
name
|
||||||
} else {
|
} else {
|
||||||
&self.from.addr
|
&self.from.addr
|
||||||
};
|
};
|
||||||
let date = self.date.format("%d/%m/%Y %H:%M").to_string();
|
let date = self.date.to_rfc3339();
|
||||||
|
|
||||||
Row::new()
|
Row::new()
|
||||||
.cell(Cell::new(id).bold_if(unseen).red())
|
.cell(Cell::new(id).bold_if(unseen).red())
|
||||||
|
|
|
@ -1,11 +1,32 @@
|
||||||
|
use std::ops;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use himalaya_lib::Envelopes;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
printer::{PrintTable, PrintTableOpts, WriteColor},
|
printer::{PrintTable, PrintTableOpts, WriteColor},
|
||||||
ui::Table,
|
ui::Table,
|
||||||
|
Envelope,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Represents the list of envelopes.
|
||||||
|
#[derive(Clone, Debug, Default, Serialize)]
|
||||||
|
pub struct Envelopes(Vec<Envelope>);
|
||||||
|
|
||||||
|
impl ops::Deref for Envelopes {
|
||||||
|
type Target = Vec<Envelope>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<himalaya_lib::Envelopes> for Envelopes {
|
||||||
|
fn from(envelopes: himalaya_lib::Envelopes) -> Self {
|
||||||
|
Envelopes(envelopes.iter().map(Envelope::from).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PrintTable for Envelopes {
|
impl PrintTable for Envelopes {
|
||||||
fn print_table(&self, writer: &mut dyn WriteColor, opts: PrintTableOpts) -> Result<()> {
|
fn print_table(&self, writer: &mut dyn WriteColor, opts: PrintTableOpts) -> Result<()> {
|
||||||
writeln!(writer)?;
|
writeln!(writer)?;
|
||||||
|
|
|
@ -83,7 +83,11 @@ pub fn flags_arg() -> Arg {
|
||||||
Arg::new(ARG_FLAGS)
|
Arg::new(ARG_FLAGS)
|
||||||
.value_name("FLAGS")
|
.value_name("FLAGS")
|
||||||
.help("The flags")
|
.help("The flags")
|
||||||
.long_help("The list of flags. It can be one of: seen, answered, flagged, deleted, draft, recent. Other flags are considered custom.")
|
.long_help(
|
||||||
|
"The list of flags.
|
||||||
|
It can be one of: seen, answered, flagged, deleted, or draft.
|
||||||
|
Other flags are considered custom.",
|
||||||
|
)
|
||||||
.num_args(1..)
|
.num_args(1..)
|
||||||
.required(true)
|
.required(true)
|
||||||
.last(true)
|
.last(true)
|
||||||
|
|
25
src/domain/flag/flag.rs
Normal file
25
src/domain/flag/flag.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
/// Represents the flag variants.
|
||||||
|
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize)]
|
||||||
|
pub enum Flag {
|
||||||
|
Seen,
|
||||||
|
Answered,
|
||||||
|
Flagged,
|
||||||
|
Deleted,
|
||||||
|
Draft,
|
||||||
|
Custom(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&himalaya_lib::Flag> for Flag {
|
||||||
|
fn from(flag: &himalaya_lib::Flag) -> Self {
|
||||||
|
match flag {
|
||||||
|
himalaya_lib::Flag::Seen => Flag::Seen,
|
||||||
|
himalaya_lib::Flag::Answered => Flag::Answered,
|
||||||
|
himalaya_lib::Flag::Flagged => Flag::Flagged,
|
||||||
|
himalaya_lib::Flag::Deleted => Flag::Deleted,
|
||||||
|
himalaya_lib::Flag::Draft => Flag::Draft,
|
||||||
|
himalaya_lib::Flag::Custom(flag) => Flag::Custom(flag.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
src/domain/flag/flags.rs
Normal file
21
src/domain/flag/flags.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use serde::Serialize;
|
||||||
|
use std::{collections::HashSet, ops};
|
||||||
|
|
||||||
|
use crate::Flag;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
|
||||||
|
pub struct Flags(pub HashSet<Flag>);
|
||||||
|
|
||||||
|
impl ops::Deref for Flags {
|
||||||
|
type Target = HashSet<Flag>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<himalaya_lib::Flags> for Flags {
|
||||||
|
fn from(flags: himalaya_lib::Flags) -> Self {
|
||||||
|
Flags(flags.iter().map(Flag::from).collect())
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,2 +1,8 @@
|
||||||
pub mod args;
|
pub mod args;
|
||||||
pub mod handlers;
|
pub mod handlers;
|
||||||
|
|
||||||
|
pub mod flag;
|
||||||
|
pub use flag::*;
|
||||||
|
|
||||||
|
pub mod flags;
|
||||||
|
pub use flags::*;
|
||||||
|
|
|
@ -1,7 +1,24 @@
|
||||||
use himalaya_lib::folder::Folder;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::ui::{Cell, Row, Table};
|
use crate::ui::{Cell, Row, Table};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, Serialize)]
|
||||||
|
pub struct Folder {
|
||||||
|
pub delim: String,
|
||||||
|
pub name: String,
|
||||||
|
pub desc: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&himalaya_lib::Folder> for Folder {
|
||||||
|
fn from(folder: &himalaya_lib::Folder) -> Self {
|
||||||
|
Folder {
|
||||||
|
delim: folder.delim.clone(),
|
||||||
|
name: folder.name.clone(),
|
||||||
|
desc: folder.desc.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Table for Folder {
|
impl Table for Folder {
|
||||||
fn head() -> Row {
|
fn head() -> Row {
|
||||||
Row::new()
|
Row::new()
|
||||||
|
|
|
@ -1,11 +1,31 @@
|
||||||
|
use std::ops;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use himalaya_lib::folder::Folders;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
printer::{PrintTable, PrintTableOpts, WriteColor},
|
printer::{PrintTable, PrintTableOpts, WriteColor},
|
||||||
ui::Table,
|
ui::Table,
|
||||||
|
Folder,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, Serialize)]
|
||||||
|
pub struct Folders(Vec<Folder>);
|
||||||
|
|
||||||
|
impl ops::Deref for Folders {
|
||||||
|
type Target = Vec<Folder>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<himalaya_lib::Folders> for Folders {
|
||||||
|
fn from(folders: himalaya_lib::Folders) -> Self {
|
||||||
|
Folders(folders.iter().map(Folder::from).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PrintTable for Folders {
|
impl PrintTable for Folders {
|
||||||
fn print_table(&self, writer: &mut dyn WriteColor, opts: PrintTableOpts) -> Result<()> {
|
fn print_table(&self, writer: &mut dyn WriteColor, opts: PrintTableOpts) -> Result<()> {
|
||||||
writeln!(writer)?;
|
writeln!(writer)?;
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use himalaya_lib::{AccountConfig, Backend};
|
use himalaya_lib::{AccountConfig, Backend};
|
||||||
|
|
||||||
use crate::printer::{PrintTableOpts, Printer};
|
use crate::{
|
||||||
|
printer::{PrintTableOpts, Printer},
|
||||||
|
Folders,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn expunge<P: Printer, B: Backend + ?Sized>(
|
pub fn expunge<P: Printer, B: Backend + ?Sized>(
|
||||||
folder: &str,
|
folder: &str,
|
||||||
|
@ -22,7 +25,7 @@ pub fn list<P: Printer, B: Backend + ?Sized>(
|
||||||
printer: &mut P,
|
printer: &mut P,
|
||||||
backend: &mut B,
|
backend: &mut B,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let folders = backend.list_folders()?;
|
let folders: Folders = backend.list_folders()?.into();
|
||||||
printer.print_table(
|
printer.print_table(
|
||||||
// TODO: remove Box
|
// TODO: remove Box
|
||||||
Box::new(folders),
|
Box::new(folders),
|
||||||
|
|
Loading…
Reference in a new issue