@@ -815,7 +815,7 @@ pub fn gen_report(year: i32, month: u32) {
815815 println ! ( "{}" , print_calendar( year, month, dates) ) ;
816816
817817 // Most used tags
818- println ! ( "{}" , "Most used tags:" . yellow( ) . underline ( ) ) ;
818+ println ! ( "{}" , "Most used tags:" . yellow( ) . bold ( ) ) ;
819819 let file_tags = get_tags_from_file ( & filename) ;
820820 let mut freq_map: HashMap < String , u32 > = HashMap :: new ( ) ;
821821 for item in file_tags. iter ( ) {
@@ -841,6 +841,71 @@ pub fn gen_report(year: i32, month: u32) {
841841 }
842842 }
843843 println ! ( "{}" , table) ;
844+
845+ let events_vec = read_events ( ) ;
846+ let today = NaiveDate :: from_ymd_opt (
847+ Local :: now ( ) . year ( ) ,
848+ Local :: now ( ) . month ( ) ,
849+ Local :: now ( ) . day ( ) ,
850+ )
851+ . unwrap ( ) ;
852+ let mut upcoming: Vec < String > = Vec :: new ( ) ;
853+ let mut completed: Vec < String > = Vec :: new ( ) ;
854+ for event in events_vec {
855+ let diff = ( event. 0 - today) . num_days ( ) ;
856+ if diff == 0 {
857+ upcoming. push ( format ! (
858+ "[{}] {}: {}" ,
859+ event. 0 . format( "%Y-%m-%d" ) . to_string( ) . cyan( ) ,
860+ "TODAY!" . red( ) . underline( ) ,
861+ event. 1
862+ ) ) ;
863+ } else if diff == 1 {
864+ upcoming. push ( format ! (
865+ "[{}] {} day from now: {}" ,
866+ event. 0 . format( "%Y-%m-%d" ) . to_string( ) . cyan( ) ,
867+ diff. to_string( ) . yellow( ) ,
868+ event. 1
869+ ) ) ;
870+ } else if diff > 1 && diff <= 7 {
871+ upcoming. push ( format ! (
872+ "[{}] {} days from now: {}" ,
873+ event. 0 . format( "%Y-%m-%d" ) . to_string( ) . cyan( ) ,
874+ diff. to_string( ) . yellow( ) ,
875+ event. 1
876+ ) ) ;
877+ } else if diff > 8 && diff <= 30 {
878+ upcoming. push ( format ! (
879+ "[{}] {} days from now: {}" ,
880+ event. 0 . format( "%Y-%m-%d" ) . to_string( ) . cyan( ) ,
881+ diff. to_string( ) . bold( ) ,
882+ event. 1
883+ ) ) ;
884+ } else if diff == -1 {
885+ completed. push ( format ! (
886+ "[{}] {} day ago: {}" ,
887+ event. 0 . format( "%Y-%m-%d" ) . to_string( ) . cyan( ) ,
888+ ( -diff) . to_string( ) . bold( ) ,
889+ event. 1
890+ ) ) ;
891+ } else if diff < -1 && diff >= -30 {
892+ completed. push ( format ! (
893+ "[{}] {} days ago: {}" ,
894+ event. 0 . format( "%Y-%m-%d" ) . to_string( ) . cyan( ) ,
895+ ( -diff) . to_string( ) . bold( ) ,
896+ event. 1
897+ ) ) ;
898+ }
899+ }
900+
901+ println ! ( "\n {}" , "Upcoming Events:" . yellow( ) . bold( ) ) ;
902+ for item in upcoming {
903+ println ! ( "{}" , item) ;
904+ }
905+ println ! ( "\n {}" , "Recently completed Events:" . yellow( ) . bold( ) ) ;
906+ for item in completed {
907+ println ! ( "{}" , item) ;
908+ }
844909}
845910
846911/// Generates a report for a year.
@@ -1007,3 +1072,64 @@ pub fn gen_report_year(year: i32) {
10071072 println ! ( "{}" , "Most used tags:" . yellow( ) . underline( ) ) ;
10081073 println ! ( "{}" , table) ;
10091074}
1075+
1076+ pub fn read_events ( ) -> Vec < ( NaiveDate , String ) > {
1077+ let file_result = File :: open ( format ! ( "{}/jrnl_folder/events.md" , get_default_path( ) ) ) ;
1078+ let file = match file_result {
1079+ Ok ( file) => file,
1080+ Err ( e) => match e. kind ( ) {
1081+ // If the file is not found, say that it doesn't exist, instead of panicking.
1082+ ErrorKind :: NotFound => {
1083+ eprintln ! (
1084+ "{}" ,
1085+ "`events.md` does not exist in your `jrnl_folder`. \n Please make it for this to work." . red( )
1086+ ) ;
1087+ process:: exit ( 1 ) ;
1088+ }
1089+ other => panic ! ( "Error opening file: {other}" ) ,
1090+ } ,
1091+ } ;
1092+
1093+ let reader: BufReader < File > = BufReader :: new ( file) ; // Reader to read by lines
1094+ let mut output: Vec < ( NaiveDate , String ) > = Vec :: new ( ) ;
1095+
1096+ let mut line_number = 0 ;
1097+ for line in reader. lines ( ) {
1098+ line_number += 1 ;
1099+ let cur_line: String = match line {
1100+ Ok ( line) => line. clone ( ) ,
1101+ Err ( e) => {
1102+ eprintln ! ( "{}" , e. to_string( ) . red( ) ) ;
1103+ "" . to_string ( )
1104+ }
1105+ } ;
1106+
1107+ if cur_line. starts_with ( '-' ) {
1108+ let parts: Vec < & str > = cur_line. split ( & [ '[' , ']' ] [ ..] ) . collect ( ) ;
1109+ if parts. len ( ) != 3 {
1110+ continue ;
1111+ }
1112+ let date_parts: Vec < & str > = parts[ 1 ] . split ( '-' ) . collect ( ) ;
1113+ let mut u32_date_parts: Vec < u32 > = Vec :: new ( ) ;
1114+ for item in date_parts {
1115+ let new_item: u32 = item. parse ( ) . unwrap_or ( 0 ) ;
1116+ u32_date_parts. push ( new_item) ;
1117+ }
1118+ let date_result =
1119+ NaiveDate :: from_ymd_opt ( Local :: now ( ) . year ( ) , u32_date_parts[ 0 ] , u32_date_parts[ 1 ] ) ;
1120+ let date = match date_result {
1121+ Some ( d) => d,
1122+ None => {
1123+ eprintln ! (
1124+ "{}: Something wrong is there with your events.md file at line number {}" ,
1125+ "ERROR" . red( ) . bold( ) ,
1126+ line_number. to_string( ) . yellow( ) . bold( ) ,
1127+ ) ;
1128+ process:: exit ( 1 ) ;
1129+ }
1130+ } ;
1131+ output. push ( ( date, parts[ 2 ] . trim ( ) . to_string ( ) ) ) ;
1132+ }
1133+ }
1134+ output
1135+ }
0 commit comments