Initial implementation
This commit is contained in:
		
						commit
						f6433f0c01
					
				
					 9 changed files with 1615 additions and 0 deletions
				
			
		
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| /target | ||||
							
								
								
									
										1430
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1430
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										16
									
								
								Cargo.toml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								Cargo.toml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| [package] | ||||
| name = "afvalcalendar" | ||||
| version = "0.1.0" | ||||
| edition = "2021" | ||||
| 
 | ||||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||
| 
 | ||||
| [dependencies] | ||||
| icalendar = "0.16.0" | ||||
| serde = { version = "1.0.195", features = ["derive"] } | ||||
| tokio = { version = "1.35.1", features = ["macros", "rt-multi-thread"] } | ||||
| reqwest = { version = "0.11", features = ["cookies", "json"] } | ||||
| chrono = { version = "0.4.34", features = ["serde"] } | ||||
| serde_json = "1.0.114" | ||||
| serde_repr = "0.1.18" | ||||
| hostname = "0.3.1" | ||||
							
								
								
									
										27
									
								
								flake.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								flake.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| { | ||||
|   "nodes": { | ||||
|     "nixpkgs": { | ||||
|       "locked": { | ||||
|         "lastModified": 1708294118, | ||||
|         "narHash": "sha256-evZzmLW7qoHXf76VCepvun1esZDxHfVRFUJtumD7L2M=", | ||||
|         "owner": "nixos", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "e0da498ad77ac8909a980f07eff060862417ccf7", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "nixos", | ||||
|         "ref": "nixos-23.11", | ||||
|         "repo": "nixpkgs", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "root": { | ||||
|       "inputs": { | ||||
|         "nixpkgs": "nixpkgs" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   "root": "root", | ||||
|   "version": 7 | ||||
| } | ||||
							
								
								
									
										25
									
								
								flake.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								flake.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| { | ||||
|   description = ""; | ||||
| 
 | ||||
|   inputs = { | ||||
|     nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11"; | ||||
|   }; | ||||
| 
 | ||||
|   outputs = {nixpkgs, ...}: let | ||||
|     system = "x86_64-linux"; | ||||
|     pkgs = nixpkgs.legacyPackages.${system}; | ||||
|   in { | ||||
|     devShells.${system}.default = pkgs.mkShell { | ||||
|       packages = with pkgs; [ | ||||
|         cargo | ||||
|         clippy | ||||
|         rustc | ||||
|         rustfmt | ||||
|         rust-analyzer | ||||
| 
 | ||||
|         pkg-config | ||||
|         openssl | ||||
|       ]; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										43
									
								
								src/calendar.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/calendar.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | |||
| use chrono::{Duration, NaiveDate}; | ||||
| use icalendar::{Alarm, Calendar, Component, Event, EventLike, Property}; | ||||
| 
 | ||||
| use crate::trash::TrashType; | ||||
| 
 | ||||
| pub(crate) fn calendar_from_pickup_dates(dates: Vec<(TrashType, NaiveDate)>) -> Calendar { | ||||
|     let mut ical = Calendar::new(); | ||||
|     ical.name("Twente Milieu Afvalkalender"); | ||||
| 
 | ||||
|     let events = dates.iter().map(|date| { | ||||
|         let description = match date.0 { | ||||
|             TrashType::Grey => "Restafval wordt opgehaald", | ||||
|             TrashType::Green => "GFT wordt opgehaald", | ||||
|             TrashType::Paper => "Papier wordt opgehaald", | ||||
|             TrashType::Packages => "Verpakkingen worden opgehaald", | ||||
|         }; | ||||
| 
 | ||||
|         let color = Property::new( | ||||
|             "COLOR", | ||||
|             match date.0 { | ||||
|                 TrashType::Grey => "darkgray", | ||||
|                 TrashType::Green => "darkgreen", | ||||
|                 TrashType::Paper => "royalblue", | ||||
|                 TrashType::Packages => "darkorange", | ||||
|             }, | ||||
|         ); | ||||
| 
 | ||||
|         let reminder = Alarm::display(description, -Duration::hours(5)); | ||||
| 
 | ||||
|         Event::new() | ||||
|             .all_day(date.1) | ||||
|             .summary(description) | ||||
|             .append_property(color) | ||||
|             .alarm(reminder) | ||||
|             .done() | ||||
|     }); | ||||
| 
 | ||||
|     for event in events { | ||||
|         ical.push(event); | ||||
|     } | ||||
| 
 | ||||
|     ical.done() | ||||
| } | ||||
							
								
								
									
										10
									
								
								src/main.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/main.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | |||
| mod calendar; | ||||
| mod trash; | ||||
| 
 | ||||
| #[tokio::main] | ||||
| async fn main() { | ||||
|     let dates = trash::get_pickup_dates().await.unwrap(); | ||||
|     let calendar = calendar::calendar_from_pickup_dates(dates); | ||||
| 
 | ||||
|     calendar.print().unwrap(); | ||||
| } | ||||
							
								
								
									
										59
									
								
								src/trash.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/trash.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | |||
| use chrono::{Months, NaiveDate, NaiveDateTime, Utc}; | ||||
| use serde::Deserialize; | ||||
| use serde_repr::Deserialize_repr; | ||||
| 
 | ||||
| #[derive(Deserialize, Debug)] | ||||
| #[serde(rename_all = "camelCase")] | ||||
| struct CalendarAPIDatum { | ||||
|     pickup_dates: Vec<NaiveDateTime>, | ||||
|     pickup_type: TrashType, | ||||
| } | ||||
| 
 | ||||
| #[derive(Deserialize, Debug)] | ||||
| #[serde(rename_all = "camelCase")] | ||||
| struct CalendarAPIResponse { | ||||
|     data_list: Vec<CalendarAPIDatum>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Copy, Clone, Deserialize_repr, Debug)] | ||||
| #[repr(u8)] | ||||
| pub(crate) enum TrashType { | ||||
|     Grey = 0, | ||||
|     Green = 1, | ||||
|     Paper = 2, | ||||
|     Packages = 10, | ||||
| } | ||||
| 
 | ||||
| pub(crate) async fn get_pickup_dates() -> Result<Vec<(TrashType, NaiveDate)>, reqwest::Error> { | ||||
|     let today = Utc::now().date_naive(); | ||||
|     let next_month = (today + Months::new(1)).to_string(); | ||||
|     let today = today.to_string(); | ||||
| 
 | ||||
|     let client = reqwest::Client::new(); | ||||
| 
 | ||||
|     let params = [ | ||||
|         ("companyCode", "8d97bb56-5afd-4cbc-a651-b4f7314264b4"), | ||||
|         ("uniqueAddressID", "1300002485"), | ||||
|         ("startDate", &today), | ||||
|         ("endDate", &next_month), | ||||
|     ]; | ||||
| 
 | ||||
|     let calendar = client | ||||
|         .post("https://twentemilieuapi.ximmio.com/api/GetCalendar") | ||||
|         .form(¶ms) | ||||
|         .send() | ||||
|         .await? | ||||
|         .json::<CalendarAPIResponse>() | ||||
|         .await?; | ||||
| 
 | ||||
|     Ok(calendar | ||||
|         .data_list | ||||
|         .iter() | ||||
|         .flat_map(|datum| { | ||||
|             datum | ||||
|                 .pickup_dates | ||||
|                 .iter() | ||||
|                 .map(|date| (datum.pickup_type, NaiveDate::from(*date))) | ||||
|         }) | ||||
|         .collect::<Vec<(TrashType, NaiveDate)>>()) | ||||
| } | ||||
							
								
								
									
										4
									
								
								test.rest
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								test.rest
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | |||
| POST https://twentemilieuapi.ximmio.com/api/GetCalendar | ||||
| Content-Type: application/x-www-form-urlencoded | ||||
| 
 | ||||
| companyCode=8d97bb56-5afd-4cbc-a651-b4f7314264b4&uniqueAddressID=1300002485&startDate=2024-02-01&endDate=2024-02-29 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue