11
22use std:: error:: Error ;
33use std:: process;
4+ use std:: path:: Path ;
5+ use std:: fs:: File ;
6+ use std:: io:: prelude:: * ;
7+
48extern crate reqwest;
59extern crate serde;
610extern crate serde_json;
@@ -101,6 +105,7 @@ static GLOWING_STAR: &'static str = "\u{1F31F}";
101105
102106static ONEDAY_URL_BASE : & ' static str = "http://api.usno.navy.mil/rstt/oneday" ;
103107
108+ static CACHE_PATH : & ' static str = "/tmp/moon" ;
104109
105110fn get_today ( ) -> String {
106111 let local: DateTime < Local > = Local :: now ( ) ;
@@ -121,7 +126,52 @@ fn get_moonicode(phase: &str) -> Result<String, String> {
121126 }
122127}
123128
129+ fn read_cache ( ) -> Result < String , String > {
130+ let cache_path = Path :: new ( CACHE_PATH ) ;
131+
132+ if !cache_path. exists ( ) {
133+ return Err ( "No such file" . to_owned ( ) ) ;
134+ }
135+
136+ let mod_sys_time : std:: time:: SystemTime = cache_path. metadata ( ) . map_err ( |e| e. to_string ( ) ) ?
137+ . modified ( ) . map_err ( |e| e. to_string ( ) ) ?;
138+
139+ let mod_unix_secs : u64 = mod_sys_time. duration_since ( std:: time:: UNIX_EPOCH ) . map_err ( |e| e. to_string ( ) ) ?
140+ . as_secs ( ) ;
141+
142+ let mod_date = Local . from_utc_datetime ( & chrono:: NaiveDateTime :: from_timestamp ( mod_unix_secs as i64 , 0 ) ) . date ( ) ;
143+
144+ if mod_date != Local :: today ( ) {
145+ return Err ( "Stale cache" . to_owned ( ) ) ;
146+ }
147+
148+ // Read file
149+ let mut f = File :: open ( cache_path) . expect ( "file not found" ) ;
150+ let mut contents = String :: new ( ) ;
151+ f. read_to_string ( & mut contents)
152+ . expect ( "something went wrong reading the file" ) ;
153+
154+ Ok ( contents)
155+ }
156+
157+ fn write_cache ( phase : & str ) {
158+ let mut file = File :: create ( "/tmp/moon" ) . unwrap ( ) ;
159+ file. write_all ( phase. as_bytes ( ) ) . unwrap ( ) ;
160+ }
161+
124162fn try_main ( ) -> Result < ( ) , Box < Error > > {
163+
164+ match read_cache ( ) {
165+ Ok ( text) => {
166+ println ! ( "{}" , text) ;
167+ return Ok ( ( ) ) ;
168+ } ,
169+ Err ( e) => {
170+ // Do nothing. Maybe print something debug wise?
171+ }
172+ }
173+
174+
125175 let mut target = String :: new ( ) ;
126176 target. push_str ( ONEDAY_URL_BASE ) ;
127177 target. push_str ( "?date=" ) ;
@@ -134,15 +184,21 @@ fn try_main() -> Result<(), Box<Error>> {
134184 //println!("{}", body);
135185 let r: SunMoonResponse = serde_json:: from_str ( & body) ?;
136186
137- match get_moonicode ( & r. curphase ) {
138- Ok ( phase) => println ! ( "{}" , phase) ,
187+ let phase = get_moonicode ( & r. curphase ) ;
188+
189+ match phase {
190+ Ok ( phase) => {
191+ println ! ( "{}" , phase) ;
192+ write_cache ( & phase)
193+ } ,
139194 // TODO: Propagate this error...
140195 Err ( message) => println ! ( "Don't know phase: {}" , r. curphase)
141196 }
142197 Ok ( ( ) )
143198}
144199
145200fn main ( ) {
201+
146202 if let Err ( err) = try_main ( ) {
147203 eprintln ! ( "{}" , err) ;
148204 process:: exit ( 1 ) ;
0 commit comments