summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNora <nora.widdecke@tu-bs.de>2019-03-09 17:15:14 +0100
committerNora <nora.widdecke@tu-bs.de>2019-03-09 17:15:14 +0100
commit5607b7c2718bdc29b1eaced8821d823f31b4c1be (patch)
tree990467b3cbaf0a962ea8b40318d2069dbe66e8aa
parent9490bf527cbfd258d1c6705569d7e3dc395c5d33 (diff)
working khevent
-rw-r--r--src/actions/agenda.rs16
-rw-r--r--src/actions/index/bucketable.rs15
-rw-r--r--src/actions/prettyprint.rs2
-rw-r--r--src/actions/unroll.rs3
-rw-r--r--src/cursorfile.rs1
-rw-r--r--src/icalwrap/icalvevent.rs47
-rw-r--r--src/input.rs3
-rw-r--r--src/khevent.rs113
-rw-r--r--src/khline.rs26
-rw-r--r--src/selectors/cal.rs7
-rw-r--r--src/selectors/grep.rs5
-rw-r--r--src/selectors/mod.rs15
-rw-r--r--src/selectors/prop.rs7
13 files changed, 170 insertions, 90 deletions
diff --git a/src/actions/agenda.rs b/src/actions/agenda.rs
index b56d274..cf0ba4d 100644
--- a/src/actions/agenda.rs
+++ b/src/actions/agenda.rs
@@ -29,15 +29,15 @@ pub fn show_events(config: &Config, args: &[&str]) -> KhResult<()> {
pub fn show_events_cursor(
config: &Config,
- events: &mut Iterator<Item = IcalVEvent>,
+ events: &mut Iterator<Item = KhEvent>,
cursor: Option<&KhLine>,
) {
- let mut not_over_yet: Vec<(usize, IcalVEvent, Option<&CalendarConfig>)> = Vec::new();
+ let mut not_over_yet: Vec<(usize, KhEvent, Option<&CalendarConfig>)> = Vec::new();
let mut cals_iter = events
.enumerate()
.map(|(i, event)| {
- let config = event.get_parent().unwrap().get_calendar_name().and_then(|name| config.get_config_for_calendar(&name));
+ let config = event.get_calendar_name().and_then(|name| config.get_config_for_calendar(&name));
(i, event, config)
})
.peekable();
@@ -61,7 +61,7 @@ pub fn show_events_cursor(
maybe_print_date_line_header(&config, cur_day, start_day, &mut last_printed_day);
not_over_yet.retain( |(index, event, cal_config)| {
- let is_cursor = cursor.map(|c| c.matches(&event)).unwrap_or(false);
+ let is_cursor = cursor.map(|c| c.matches_khevent(&event)).unwrap_or(false);
maybe_print_date_line(&config, cur_day, start_day, &mut last_printed_day);
print_event_line(*cal_config, *index, &event, cur_day, is_cursor);
event.continues_after(cur_day)
@@ -69,7 +69,7 @@ pub fn show_events_cursor(
let relevant_events = cals_iter.peeking_take_while(|(_,event,_)| event.starts_on(cur_day));
for (i, event, cal_config) in relevant_events {
- let is_cursor = cursor.map(|c| c.matches(&event)).unwrap_or(false);
+ let is_cursor = cursor.map(|c| c.matches_khevent(&event)).unwrap_or(false);
maybe_print_date_line(&config, cur_day, start_day, &mut last_printed_day);
print_event_line(cal_config, i, &event, cur_day, is_cursor);
if event.continues_after(cur_day) {
@@ -112,7 +112,7 @@ fn print_date_line(date: Date<Local>) {
fn print_event_line(
config: Option<&CalendarConfig>,
index: usize,
- event: &IcalVEvent,
+ event: &KhEvent,
date: Date<Local>,
is_cursor: bool
) {
@@ -124,7 +124,7 @@ fn print_event_line(
pub fn event_line(
config: Option<&CalendarConfig>,
- event: &IcalVEvent,
+ event: &KhEvent,
cur_day: Date<Local>,
is_cursor: bool
) -> Result<String, String> {
@@ -164,7 +164,7 @@ pub fn event_line(
}
}
-impl IcalVEvent {
+impl KhEvent {
fn starts_on(&self, date: Date<Local>) -> bool {
let dtstart: Date<Local> = self.get_start().unwrap().into();
dtstart == date
diff --git a/src/actions/index/bucketable.rs b/src/actions/index/bucketable.rs
index 299d055..27ab9a6 100644
--- a/src/actions/index/bucketable.rs
+++ b/src/actions/index/bucketable.rs
@@ -2,7 +2,8 @@ use chrono::{Local, Date, Datelike, Duration};
use std::collections::HashMap;
use std::{hash, cmp};
-use crate::icalwrap::{IcalVEvent, IcalVCalendar};
+use crate::icalwrap::IcalVCalendar;
+//use crate::icalwrap::IcalVEvent;
use crate::utils::misc;
use crate::khline::KhLine;
use crate::khevent::KhEvent;
@@ -22,18 +23,19 @@ pub trait Bucketable {
}
}
-impl Bucketable for IcalVEvent {
+impl Bucketable for KhEvent {
fn get_buckets(&self) -> Result<HashMap<String, Vec<String>>, String> {
let mut result: HashMap<String, Vec<String>> = HashMap::new();
let start_date: Date<Local> = self.get_start().ok_or_else(|| format!("Invalid DTSTART in {}", self.get_uid()))?.into();
- let mut end_date: Date<Local> = self.get_end().map(|date| date.into()).unwrap_or(start_date);
+ //let mut end_date: Date<Local> = self.get_end().map(|date| date.into()).unwrap_or(start_date);
+ let mut end_date = self.get_last_relevant_date().map(|date| date.into()).unwrap_or(start_date);
// end-dtimes are non-inclusive
// so in case of date-only events, the last day of the event is dtend-1
- if self.is_allday() {
- end_date = end_date.pred();
- }
+ //if self.is_allday() {
+ //end_date = end_date.pred();
+ //}
let buckets = Self::buckets_for_interval(start_date, end_date);
let khline = KhLine::from(self);
@@ -62,6 +64,7 @@ impl Bucketable for IcalVCalendar {
fn get_buckets(&self) -> Result<HashMap<String, Vec<String>>, String> {
let mut result: HashMap<String, Vec<String>> = HashMap::new();
for event in self.events_iter() {
+ let event = KhEvent::from_event(event);
let recur_buckets = event.get_buckets()?;
result.merge(recur_buckets);
}
diff --git a/src/actions/prettyprint.rs b/src/actions/prettyprint.rs
index 51a0251..6b7fdad 100644
--- a/src/actions/prettyprint.rs
+++ b/src/actions/prettyprint.rs
@@ -6,7 +6,7 @@ use crate::KhResult;
pub fn prettyprint() -> KhResult<()> {
let lines = input::default_input_khlines()?;
for line in lines {
- let event = line.to_event()?;
+ let event = line.to_event()?.event;
prettyprint_comp(&event, line.get_path());
}
Ok(())
diff --git a/src/actions/unroll.rs b/src/actions/unroll.rs
index 27f4e10..e3c8a09 100644
--- a/src/actions/unroll.rs
+++ b/src/actions/unroll.rs
@@ -24,7 +24,8 @@ fn do_unroll(filepath: &Path) -> KhResult<()> {
let khline = path.parse::<KhLine>()?;
let cal = khline.to_cal()?;
- for event in cal.events_iter() {
+ for ical_event in cal.events_iter() {
+ let event = KhEvent::from_event(ical_event);
if event.is_recur_master() {
let recurs = event.get_recur_datetimes();
for datetime in recurs {
diff --git a/src/cursorfile.rs b/src/cursorfile.rs
index 43c9979..b1b5c64 100644
--- a/src/cursorfile.rs
+++ b/src/cursorfile.rs
@@ -3,6 +3,7 @@ use std::io;
use crate::defaults::*;
use crate::khline::KhLine;
+use crate::khevent::KhEvent;
use crate::utils::fileutil;
use crate::KhResult;
diff --git a/src/icalwrap/icalvevent.rs b/src/icalwrap/icalvevent.rs
index 1494f03..9e9ba9f 100644
--- a/src/icalwrap/icalvevent.rs
+++ b/src/icalwrap/icalvevent.rs
@@ -32,34 +32,6 @@ impl IcalComponent for IcalVEvent {
}
}
-impl KhEvent for IcalVEvent {
- fn get_start(&self) -> Option<IcalTime> {
- //TODO: should probably depend on is_recur_master, not the instance timestamp
- match self.instance_timestamp {
- Some(ref timestamp) => Some(timestamp.clone()),
- None => {
- self.get_dtstart()
- }
- }
- }
-
- fn get_end(&self) -> Option<IcalTime> {
- //TODO: should probably depend on is_recur_master, not the instance timestamp
- match self.instance_timestamp {
- Some(ref timestamp) => unsafe {
- let icalduration = ical::icalcomponent_get_duration(self.ptr);
- let dtend = ical::icaltime_add(**timestamp, icalduration);
- Some(IcalTime::from(dtend))
- },
- None => self.get_dtend()
- }
- }
-
- fn is_recur_master(&self) -> bool {
- self.has_property_rrule() && self.instance_timestamp.is_none()
- }
-}
-
impl IcalVEvent {
pub fn from_ptr_with_parent(
ptr: *mut ical::icalcomponent,
@@ -106,14 +78,6 @@ impl IcalVEvent {
}
}
- pub fn get_last_relevant_date(&self) -> Option<IcalTime> {
- if self.is_allday() {
- self.get_dtend().map(|dtend| dtend.pred())
- } else {
- self.get_dtend().map(|dtend| dtend)
- }
- }
-
pub fn has_property_rrule(&self) -> bool {
!self.get_properties(ical::icalproperty_kind_ICAL_RRULE_PROPERTY).is_empty()
}
@@ -139,17 +103,6 @@ impl IcalVEvent {
result
}
- pub fn is_recur_valid(&self) -> bool {
- if self.is_recur_master() {
- true
- } else if let Some(ref timestamp) = self.instance_timestamp {
- let recur_times = self.get_recur_datetimes();
- recur_times.contains(timestamp)
- } else {
- self.instance_timestamp.is_none()
- }
- }
-
pub fn with_internal_timestamp(&self, datetime: &IcalTime) -> IcalVEvent {
IcalVEvent {
ptr: self.ptr,
diff --git a/src/input.rs b/src/input.rs
index 44e3244..3625ad7 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -6,8 +6,9 @@ use crate::khline::{KhLine,lines_to_khlines,khlines_to_events};
use crate::utils::stdioutils;
use crate::icalwrap::IcalVEvent;
use crate::selectors::SelectFilters;
+use crate::khevent::KhEvent;
-pub fn selection(args: &[&str]) -> Result<Box<dyn Iterator<Item = IcalVEvent>>, String> {
+pub fn selection(args: &[&str]) -> Result<Box<dyn Iterator<Item = KhEvent>>, String> {
if args.is_empty() {
let khlines = default_input_khlines()?;
let events = khlines_to_events(khlines);
diff --git a/src/khevent.rs b/src/khevent.rs
index b3c10a2..0ea4889 100644
--- a/src/khevent.rs
+++ b/src/khevent.rs
@@ -1,9 +1,114 @@
use crate::icalwrap::IcalTime;
+use crate::icalwrap::IcalDuration;
+use crate::icalwrap::IcalVEvent;
-pub trait KhEvent {
- fn get_start(&self) -> Option<IcalTime>;
- fn get_end(&self) -> Option<IcalTime>;
- fn is_recur_master(&self) -> bool;
+pub struct KhEvent {
+ //TODO event should be private
+ pub event: IcalVEvent,
+ instance_timestamp: Option<IcalTime>,
}
+impl KhEvent {
+ pub fn get_start(&self) -> Option<IcalTime> {
+ //TODO: should probably depend on is_recur_master, not the instance timestamp
+ match self.instance_timestamp {
+ Some(ref timestamp) => Some(timestamp.clone()),
+ None => {
+ self.event.get_dtstart()
+ }
+ }
+ }
+
+ pub fn get_end(&self) -> Option<IcalTime> {
+ //TODO: should probably depend on is_recur_master, not the instance timestamp
+ match self.instance_timestamp {
+ Some(ref timestamp) => unsafe {
+ let dur = self.get_duration().unwrap();
+ let dtend = timestamp.to_owned() + dur;
+ Some(dtend)
+ //let icalduration = ical::icalcomponent_get_duration(self.event.ptr);
+ //let dtend = ical::icaltime_add(**timestamp, icalduration);
+ //Some(IcalTime::from(dtend))
+ },
+ None => self.event.get_dtend()
+ }
+ }
+
+ pub fn get_calendar_name(&self) -> Option<String> {
+ self.event.get_parent().and_then(|cal| cal.get_calendar_name())
+ }
+
+ pub fn is_allday(&self) -> bool {
+ self.event.is_allday()
+ }
+
+ pub fn get_duration(&self) -> Option<IcalDuration> {
+ self.event.get_duration()
+ }
+
+ pub fn get_summary(&self) -> Option<String> {
+ self.event.get_summary()
+ }
+
+ pub fn get_description(&self) -> Option<String> {
+ self.event.get_description()
+ }
+
+ pub fn get_location(&self) -> Option<String> {
+ self.event.get_location()
+ }
+
+ pub fn get_uid(&self) -> String {
+ self.event.get_uid()
+ }
+
+ pub fn get_last_relevant_date(&self) -> Option<IcalTime> {
+ //TODO this is still wrong
+ //events can end at 00:00
+ if self.is_allday() {
+ self.get_end().map(|dtend| dtend.pred())
+ } else {
+ self.get_end().map(|dtend| dtend)
+ }
+ }
+
+ pub fn is_recur_master(&self) -> bool {
+ self.event.has_property_rrule() && self.instance_timestamp.is_none()
+ }
+
+ pub fn is_recur_valid(&self) -> bool {
+ if self.is_recur_master() {
+ true
+ } else if let Some(ref timestamp) = self.instance_timestamp {
+ let recur_times = self.event.get_recur_datetimes();
+ recur_times.contains(timestamp)
+ } else {
+ self.instance_timestamp.is_none()
+ }
+ }
+
+ pub fn get_recur_instances(&self) -> impl Iterator<Item = KhEvent> + '_ {
+ self.event.get_recur_instances().map(|event| KhEvent::from_event(event))
+ }
+
+
+ pub fn get_recur_datetimes(&self) -> Vec<IcalTime> {
+ self.event.get_recur_datetimes()
+ }
+
+ pub fn from_event(event: IcalVEvent) -> Self {
+ Self {
+ event,
+ instance_timestamp: None,
+ }
+ }
+
+ pub fn from_event_with_timestamp(event: IcalVEvent, instance_timestamp: Option<IcalTime>) -> Self {
+ Self {
+ event,
+ instance_timestamp,
+ }
+ }
+
+}
diff --git a/src/khline.rs b/src/khline.rs
index ffb79a3..03a6407 100644
--- a/src/khline.rs
+++ b/src/khline.rs
@@ -31,19 +31,24 @@ impl KhLine {
Ok(calendar)
}
- pub fn to_event(&self) -> io::Result<IcalVEvent> {
+ pub fn to_event(&self) -> io::Result<KhEvent> {
let calendar = self.to_cal()?;
let mut event = calendar.get_first_event();
- if let Some(ref time) = self.time {
- event = event.with_internal_timestamp(time);
- }
- Ok(event)
+ Ok(KhEvent::from_event_with_timestamp(event, self.time.clone()))
+ //if let Some(ref time) = self.time {
+ //event = event.with_internal_timestamp(time);
+ //}
+ //Ok(event)
}
pub fn with_index(self, index: usize) -> Self {
Self { path: self.path, time: self.time, index: Some(index) }
}
+ pub fn matches_khevent(&self, event: &KhEvent) -> bool {
+ self == &KhLine::from(event)
+ }
+
pub fn matches(&self, event: &IcalVEvent) -> bool {
self == &KhLine::from(event)
}
@@ -66,6 +71,15 @@ impl KhLine {
impl From<&IcalVEvent> for KhLine {
fn from(event: &IcalVEvent) -> Self {
let path = event.get_parent().unwrap().get_path().unwrap().to_path_buf();
+ let time = event.get_dtstart();
+
+ KhLine{ path, time, index: None }
+ }
+}
+
+impl From<&KhEvent> for KhLine {
+ fn from(event: &KhEvent) -> Self {
+ let path = event.event.get_parent().unwrap().get_path().unwrap().to_path_buf();
let time = event.get_start();
KhLine{ path, time, index: None }
@@ -127,7 +141,7 @@ pub fn lines_to_khlines_indexed(lines: impl Iterator<Item = String>) -> impl Ite
.flatten()
}
-pub fn khlines_to_events(lines: impl Iterator<Item = KhLine>) -> impl Iterator<Item = IcalVEvent> {
+pub fn khlines_to_events(lines: impl Iterator<Item = KhLine>) -> impl Iterator<Item = KhEvent> {
lines.map(|line| line.to_event()).flatten()
}
diff --git a/src/selectors/cal.rs b/src/selectors/cal.rs
index 9567742..aab39b1 100644
--- a/src/selectors/cal.rs
+++ b/src/selectors/cal.rs
@@ -1,6 +1,7 @@
use super::*;
-use crate::icalwrap::IcalVEvent;
+//use crate::icalwrap::IcalVEvent;
+use crate::khevent::KhEvent;
pub struct CalendarFilter {
cal_names: Vec<String>
@@ -16,8 +17,8 @@ impl SelectFilter for CalendarFilter {
!self.cal_names.is_empty()
}
- fn includes(&self, event: &IcalVEvent) -> bool {
- event.get_parent()
+ fn includes(&self, event: &KhEvent) -> bool {
+ event.event.get_parent()
.and_then(|cal| cal.get_path())
.and_then(|path| path.parent())
.map(|path| path.to_string_lossy().to_lowercase())
diff --git a/src/selectors/grep.rs b/src/selectors/grep.rs
index 47ae617..d0dd327 100644
--- a/src/selectors/grep.rs
+++ b/src/selectors/grep.rs
@@ -1,6 +1,7 @@
use super::*;
-use crate::icalwrap::IcalVEvent;
+//use crate::icalwrap::IcalVEvent;
+use crate::khevent::KhEvent;
pub struct GrepFilter {
terms: Vec<String>
@@ -16,7 +17,7 @@ impl SelectFilter for GrepFilter {
!self.terms.is_empty()
}
- fn includes(&self, event: &IcalVEvent) -> bool {
+ fn includes(&self, event: &KhEvent) -> bool {
for term in &self.terms {
if let Some(summary) = event.get_summary() {
if summary.to_lowercase().contains(term) {
diff --git a/src/selectors/mod.rs b/src/selectors/mod.rs
index 940c1b3..7092cd0 100644
--- a/src/selectors/mod.rs
+++ b/src/selectors/mod.rs
@@ -1,7 +1,6 @@
use std::collections::HashMap;
use crate::khline::{KhLine,khlines_to_events};
-use crate::icalwrap::IcalVEvent;
use crate::khevent::KhEvent;
use self::daterange::{SelectFilterFrom,SelectFilterTo};
@@ -28,7 +27,7 @@ pub struct SelectFilters {
pub trait SelectFilter {
fn add_term(&mut self, it: &mut dyn Iterator<Item = &&str>);
fn is_not_empty(&self) -> bool;
- fn includes(&self, event: &IcalVEvent) -> bool;
+ fn includes(&self, event: &KhEvent) -> bool;
}
impl SelectFilters {
@@ -91,13 +90,13 @@ impl SelectFilters {
Ok(SelectFilters { from, to, range, others })
}
- fn line_is_from(&self, event: &IcalVEvent) -> bool {
+ fn line_is_from(&self, event: &KhEvent) -> bool {
let starts_after = self.from.includes_date(event.get_start().unwrap().into());
let ends_after = self.from.includes_date(event.get_end().unwrap().into());
starts_after || ends_after
}
- fn line_is_to(&self, event: &IcalVEvent) -> bool {
+ fn line_is_to(&self, event: &KhEvent) -> bool {
self.to.includes_date(event.get_start().unwrap().into())
}
@@ -109,22 +108,22 @@ impl SelectFilters {
}
}
- fn others(&self, event: &IcalVEvent) -> bool {
+ fn others(&self, event: &KhEvent) -> bool {
self.others.is_empty() || self.others.iter().any(|filter| filter.includes(event))
}
- pub fn is_selected(&self, event: &IcalVEvent) -> bool {
+ pub fn is_selected(&self, event: &KhEvent) -> bool {
self.line_is_from(event) && self.line_is_to(event) && self.others(event)
}
- pub fn is_selected_index(&self, index: usize, event: &IcalVEvent) -> bool {
+ pub fn is_selected_index(&self, index: usize, event: &KhEvent) -> bool {
self.filter_index(index) && self.line_is_from(event) && self.line_is_to(event) && self.others(event)
}
pub fn filter_khlines(
self,
khlines: impl Iterator<Item = KhLine>,
- ) -> impl Iterator<Item = IcalVEvent> {
+ ) -> impl Iterator<Item = KhEvent> {
let events = khlines_to_events(khlines);
events
.enumerate()
diff --git a/src/selectors/prop.rs b/src/selectors/prop.rs
index 4f644d4..c5188ee 100644
--- a/src/selectors/prop.rs
+++ b/src/selectors/prop.rs
@@ -2,7 +2,8 @@ use std::collections::HashMap;
use super::*;
-use crate::icalwrap::IcalVEvent;
+use crate::khevent::KhEvent;
+//use crate::icalwrap::IcalVEvent;
use crate::icalwrap::IcalComponent;
pub struct PropFilter {
@@ -22,9 +23,9 @@ impl SelectFilter for PropFilter {
!self.terms.is_empty()
}
- fn includes(&self, event: &IcalVEvent) -> bool {
+ fn includes(&self, event: &KhEvent) -> bool {
for (term, values) in &self.terms {
- for prop in event.get_properties_by_name(term) {
+ for prop in event.event.get_properties_by_name(term) {
let value = prop.get_value().to_lowercase();
if values.iter().any(|x| value.contains(x)) {
return true;