diff --git a/Cargo.lock b/Cargo.lock index 1fe9c91..b88442b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" +checksum = "c91f1f46651137be86f3a2b9a8359f9ab421d04d941c62b5982e1ca21113adf9" [[package]] name = "atty" @@ -90,15 +90,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "6127248204b9aba09a362f6c930ef6a78f2c1b2215f8a7b398c06e1083f17af0" dependencies = [ - "libc", + "js-sys", "num-integer", "num-traits", "serde", "time", + "wasm-bindgen", "winapi", ] @@ -501,7 +502,7 @@ checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", - "itoa 1.0.2", + "itoa 1.0.3", ] [[package]] @@ -548,7 +549,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 1.0.2", + "itoa 1.0.3", "pin-project-lite", "socket2", "tokio", @@ -631,9 +632,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" [[package]] name = "jni" @@ -672,9 +673,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b" [[package]] name = "libxml" @@ -955,28 +956,29 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "proc-macro-crate" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +checksum = "26d50bfb8c23f23915855a00d98b5a35ef2e0b871bb52937bacadb798fbb66c8" dependencies = [ + "once_cell", "thiserror", "toml", ] [[package]] name = "proc-macro2" -version = "1.0.42" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] @@ -1072,9 +1074,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24c8ad4f0c00e1eb5bc7614d236a7f1300e3dbd76b68cac8e06fb00b015ad8d8" +checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" [[package]] name = "rusty-hook" @@ -1090,9 +1092,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "same-file" @@ -1138,18 +1140,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.140" +version = "1.0.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" +checksum = "e590c437916fb6b221e1d00df6e3294f3fccd70ca7e92541c475d6ed6ef5fee2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.140" +version = "1.0.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" +checksum = "34b5b8d809babe02f538c2cfec6f2c1ed10804c0e5a6a041a049a4f5588ccc2e" dependencies = [ "proc-macro2", "quote", @@ -1158,11 +1160,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" +checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" dependencies = [ - "itoa 1.0.2", + "itoa 1.0.3", "ryu", "serde", ] @@ -1174,7 +1176,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.2", + "itoa 1.0.3", "ryu", "serde", ] @@ -1238,9 +1240,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.98" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" dependencies = [ "proc-macro2", "quote", @@ -1278,18 +1280,18 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" dependencies = [ "proc-macro2", "quote", @@ -1425,9 +1427,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" [[package]] name = "unicode-normalization" diff --git a/examples/example-schedule.csv b/examples/example-schedule.csv index 7423889..bd8e0b4 100644 --- a/examples/example-schedule.csv +++ b/examples/example-schedule.csv @@ -5,7 +5,7 @@ "2022-01-04","martedì",, "2022-01-05","mercoledì",, "2022-01-06","giovedì",, -"2022-01-07","venerdì",, +"2022-01-07","venerdì",,"https://ricette.giallozafferano.it/Cordon-bleu.html" "2022-01-08","sabato",, "2022-01-09","domenica","https://ricette.giallozafferano.it/Pollo-alla-cacciatora.html","https://ricette.giallozafferano.it/Vellutata-di-porri-con-crostini-saporiti.html" "2022-01-10","lunedì",, @@ -16,17 +16,17 @@ "2022-01-15","sabato","https://ricette.giallozafferano.it/Orata-al-forno.html","https://ricette.giallozafferano.it/Risotto-radicchio-e-pancetta.html" "2022-01-16","domenica",, "2022-01-17","lunedì",,"https://ricette.giallozafferano.it/Spatzle-di-spinaci.html" -"2022-01-18","martedì",, +"2022-01-18","martedì",,"https://ricette.giallozafferano.it/Hamburger-di-ceci.html" "2022-01-19","mercoledì",, "2022-01-20","giovedì",, "2022-01-21","venerdì",, -"2022-01-22","sabato","https://ricette.giallozafferano.it/Gnocchi-alla-sorrentina.html", +"2022-01-22","sabato","https://ricette.giallozafferano.it/Gnocchi-alla-sorrentina.html","https://www.chefkoch.de/rezepte/2183131350572745/Deftige-Gulaschsuppe.html" "2022-01-23","domenica",, "2022-01-24","lunedì",, "2022-01-25","martedì",, "2022-01-26","mercoledì",, "2022-01-27","giovedì",, -"2022-01-28","venerdì",, +"2022-01-28","venerdì",,"https://ricette.giallozafferano.it/Polpette-di-spinaci-e-ricotta.html" "2022-01-29","sabato",,"https://ricette.giallozafferano.it/Costine-al-forno.html" "2022-01-30","domenica",, "2022-01-31","lunedì",, @@ -41,7 +41,7 @@ "2022-02-09","mercoledì",,"https://ricette.giallozafferano.it/Vellutata-di-porri-con-crostini-saporiti.html" "2022-02-10","giovedì",, "2022-02-11","venerdì",, -"2022-02-12","sabato",, +"2022-02-12","sabato",,"https://ricette.giallozafferano.it/Spezzatino-alla-Guinness.html" "2022-02-13","domenica",,"https://ricette.giallozafferano.it/Spatzle-di-spinaci.html" "2022-02-14","lunedì",, "2022-02-15","martedì",, @@ -55,14 +55,14 @@ "2022-02-23","mercoledì",, "2022-02-24","giovedì",,"https://ricette.giallozafferano.it/Orata-al-forno.html" "2022-02-25","venerdì",,"https://ricette.giallozafferano.it/Torta-rustica.html" -"2022-02-26","sabato","https://ricette.giallozafferano.it/Gnudi.html", +"2022-02-26","sabato","https://ricette.giallozafferano.it/Gnudi.html","https://www.chefkoch.de/rezepte/2183131350572745/Deftige-Gulaschsuppe.html" "2022-02-27","domenica",, "2022-02-28","lunedì",, "2022-03-01","martedì",, "2022-03-02","mercoledì",,"https://ricette.giallozafferano.it/Mezze-maniche-al-tonno.html" "2022-03-03","giovedì",, -"2022-03-04","venerdì",, -"2022-03-05","sabato",, +"2022-03-04","venerdì",,"https://ricette.giallozafferano.it/Cordon-bleu.html" +"2022-03-05","sabato",,"https://ricette.giallozafferano.it/Ragu-di-seitan.html" "2022-03-06","domenica","https://ricette.giallozafferano.it/Torta-Pasqualina.html", "2022-03-07","lunedì",, "2022-03-08","martedì",,"https://ricette.giallozafferano.it/Strozzapreti-cacio-cozze-e-pepe.html" @@ -82,33 +82,33 @@ "2022-03-22","martedì",, "2022-03-23","mercoledì",, "2022-03-24","giovedì",, -"2022-03-25","venerdì",, +"2022-03-25","venerdì",,"https://ricette.giallozafferano.it/Polpette-di-spinaci-e-ricotta.html" "2022-03-26","sabato","https://ricette.giallozafferano.it/Orata-al-forno.html", "2022-03-27","domenica",, "2022-03-28","lunedì",, "2022-03-29","martedì",, "2022-03-30","mercoledì",, -"2022-03-31","giovedì",, +"2022-03-31","giovedì",,"https://ricette.giallozafferano.it/Hamburger-di-ceci.html" "2022-04-01","venerdì",, -"2022-04-02","sabato",, +"2022-04-02","sabato",,"https://ricette.giallozafferano.it/Moussaka.html" "2022-04-03","domenica",, "2022-04-04","lunedì",, "2022-04-05","martedì",, "2022-04-06","mercoledì",, "2022-04-07","giovedì",, -"2022-04-08","venerdì",, +"2022-04-08","venerdì",,"https://ricette.giallozafferano.it/Ratatouille.html" "2022-04-09","sabato",, "2022-04-10","domenica",, "2022-04-11","lunedì",, "2022-04-12","martedì",, "2022-04-13","mercoledì",,"https://ricette.giallozafferano.it/Mezze-maniche-al-tonno.html" "2022-04-14","giovedì",, -"2022-04-15","venerdì",, +"2022-04-15","venerdì",,"https://ricette.giallozafferano.it/Peperoni-ripieni-di-carne-e-salsiccia.html" "2022-04-16","sabato",,"https://ricette.giallozafferano.it/Couscous-alla-marocchina.html" "2022-04-17","domenica",, "2022-04-18","lunedì",, "2022-04-19","martedì",, -"2022-04-20","mercoledì",, +"2022-04-20","mercoledì",,"https://ricette.giallozafferano.it/Pasta-con-crema-di-peperoni.html" "2022-04-21","giovedì",, "2022-04-22","venerdì",,"https://ricette.giallozafferano.it/Risotto-agli-asparagi-e-scampi.html" "2022-04-23","sabato",, @@ -118,44 +118,44 @@ "2022-04-27","mercoledì",,"https://ricette.giallozafferano.it/Orata-al-forno.html" "2022-04-28","giovedì",, "2022-04-29","venerdì",,"https://ricette.giallozafferano.it/Cordon-bleu-di-melanzane.html" -"2022-04-30","sabato",, +"2022-04-30","sabato",,"https://ricette.giallozafferano.it/Hamburger-di-ceci.html" "2022-05-01","domenica",, "2022-05-02","lunedì",, "2022-05-03","martedì",, "2022-05-04","mercoledì",, -"2022-05-05","giovedì",, +"2022-05-05","giovedì",,"https://ricette.giallozafferano.it/Scaloppine-saporite-con-cotto-e-formaggio.html" "2022-05-06","venerdì",, -"2022-05-07","sabato",, +"2022-05-07","sabato",,"https://ricette.giallozafferano.it/Moussaka.html" "2022-05-08","domenica",, "2022-05-09","lunedì",, "2022-05-10","martedì",, "2022-05-11","mercoledì",,"https://ricette.giallozafferano.it/Mezze-maniche-al-tonno.html" "2022-05-12","giovedì",, -"2022-05-13","venerdì",, +"2022-05-13","venerdì",,"https://ricette.giallozafferano.it/Spiedini-di-pollo.html" "2022-05-14","sabato",, "2022-05-15","domenica",, "2022-05-16","lunedì",, "2022-05-17","martedì",, "2022-05-18","mercoledì",,"https://ricette.giallozafferano.it/Risotto-agli-asparagi-e-scampi.html" -"2022-05-19","giovedì",, -"2022-05-20","venerdì",, +"2022-05-19","giovedì",,"https://ricette.giallozafferano.it/Ratatouille.html" +"2022-05-20","venerdì",,"https://ricette.giallozafferano.it/Spaghetti-di-riso-con-carne-e-verdure.html" "2022-05-21","sabato",,"https://ricette.giallozafferano.it/Couscous-alla-marocchina.html" "2022-05-22","domenica","https://ricette.giallozafferano.it/Orata-al-forno.html", "2022-05-23","lunedì",, -"2022-05-24","martedì",, +"2022-05-24","martedì",,"https://ricette.giallozafferano.it/Spaghetti-poveri.html" "2022-05-25","mercoledì",, "2022-05-26","giovedì",,"https://ricette.giallozafferano.it/Saltimbocca-alla-Romana.html" -"2022-05-27","venerdì",, +"2022-05-27","venerdì",,"https://ricette.giallozafferano.it/Ratatouille.html" "2022-05-28","sabato",, "2022-05-29","domenica","https://ricette.giallozafferano.it/Polpo-alla-Luciana.html", "2022-05-30","lunedì",, -"2022-05-31","martedì",, +"2022-05-31","martedì",,"https://ricette.giallozafferano.it/Pasta-con-pomodorini-e-stracchino.html" "2022-06-01","mercoledì",,"https://ricette.giallozafferano.it/Riso-alla-cantonese.html" -"2022-06-02","giovedì",, -"2022-06-03","venerdì",, -"2022-06-04","sabato",, +"2022-06-02","giovedì",,"https://ricette.giallozafferano.it/Bocconcini-di-pollo-con-yogurt-e-curcuma.html" +"2022-06-03","venerdì",,"https://ricette.giallozafferano.it/Insalata-con-uova-strapazzate.html" +"2022-06-04","sabato",,"https://ricette.giallozafferano.it/Garganelli-con-pesto-di-zucchine-e-gamberetti.html" "2022-06-05","domenica",, -"2022-06-06","lunedì",, +"2022-06-06","lunedì",,"https://ricette.giallozafferano.it/Insalata-Shirazi.html" "2022-06-07","martedì",,"https://ricette.giallozafferano.it/Pasta-fredda-con-pesto-senz-aglio.html" "2022-06-08","mercoledì",, "2022-06-09","giovedì",, @@ -176,72 +176,72 @@ "2022-06-24","venerdì",, "2022-06-25","sabato","https://ricette.giallozafferano.it/Orata-al-forno.html", "2022-06-26","domenica",, -"2022-06-27","lunedì",, +"2022-06-27","lunedì",,"https://ricette.giallozafferano.it/Spaghetti-poveri.html" "2022-06-28","martedì",, -"2022-06-29","mercoledì",, -"2022-06-30","giovedì",, +"2022-06-29","mercoledì",,"https://ricette.giallozafferano.it/Insalata-Shirazi.html" +"2022-06-30","giovedì",,"https://ricette.giallozafferano.it/Scaloppine-saporite-con-cotto-e-formaggio.html" "2022-07-01","venerdì",, "2022-07-02","sabato",, -"2022-07-03","domenica",, -"2022-07-04","lunedì",, +"2022-07-03","domenica",,"https://ricette.giallozafferano.it/Insalata-di-bulgur-vegana.html" +"2022-07-04","lunedì",,"https://ricette.giallozafferano.it/Garganelli-con-pesto-di-zucchine-e-gamberetti.html" "2022-07-05","martedì",,"https://ricette.giallozafferano.it/Insalata-di-ceci-estiva.html" "2022-07-06","mercoledì",,"https://ricette.giallozafferano.it/Pasta-con-le-melanzane.html" "2022-07-07","giovedì",, "2022-07-08","venerdì",, -"2022-07-09","sabato",, +"2022-07-09","sabato","https://ricette.giallozafferano.it/Pasta-con-pomodorini-e-stracchino.html", "2022-07-10","domenica",, -"2022-07-11","lunedì",, +"2022-07-11","lunedì",,"https://ricette.giallozafferano.it/Insalata-con-uova-strapazzate.html" "2022-07-12","martedì",, "2022-07-13","mercoledì",,"https://ricette.giallozafferano.it/Pasta-fredda-con-pesto-senz-aglio.html" "2022-07-14","giovedì",, "2022-07-15","venerdì",,"https://ricette.giallozafferano.it/Salmorejo.html" "2022-07-16","sabato",, -"2022-07-17","domenica",, -"2022-07-18","lunedì",, +"2022-07-17","domenica",,"https://ricette.giallozafferano.it/Insalata-di-quinoa-alla-greca.html" +"2022-07-18","lunedì",,"https://ricette.giallozafferano.it/Bocconcini-di-pollo-con-yogurt-e-curcuma.html" "2022-07-19","martedì",,"https://ricette.giallozafferano.it/Verdure-gratinate-al-forno.html" "2022-07-20","mercoledì",, "2022-07-21","giovedì",,"https://ricette.giallozafferano.it/Insalata-di-pasta-Mediterranea.html" "2022-07-22","venerdì",, "2022-07-23","sabato",,"https://ricette.giallozafferano.it/Cocotte-di-quinoa.html" "2022-07-24","domenica",, -"2022-07-25","lunedì",, -"2022-07-26","martedì",, -"2022-07-27","mercoledì",, +"2022-07-25","lunedì",,"https://ricette.giallozafferano.it/Tempeh-alle-verdure.html" +"2022-07-26","martedì",,"https://ricette.giallozafferano.it/Spiedini-di-pollo.html" +"2022-07-27","mercoledì",,"https://ricette.giallozafferano.it/Pasta-con-crema-di-peperoni.html" "2022-07-28","giovedì",, "2022-07-29","venerdì",,"https://ricette.giallozafferano.it/Orata-al-forno.html" "2022-07-30","sabato",, "2022-07-31","domenica",, "2022-08-01","lunedì",,"https://ricette.giallozafferano.it/Riso-freddo-con-tonno-zucchine-e-limone.html" -"2022-08-02","martedì",, +"2022-08-02","martedì",,"https://ricette.giallozafferano.it/Insalata-Shirazi.html" "2022-08-03","mercoledì",,"https://ricette.giallozafferano.it/Pasta-fredda-con-pesto-senz-aglio.html" "2022-08-04","giovedì",,"https://ricette.giallozafferano.it/Petto-di-pollo-ai-peperoni.html" -"2022-08-05","venerdì",, -"2022-08-06","sabato",, +"2022-08-05","venerdì",,"https://ricette.giallozafferano.it/Pasta-con-pomodorini-e-stracchino.html" +"2022-08-06","sabato","https://ricette.giallozafferano.it/Spaghetti-di-riso-con-carne-e-verdure.html", "2022-08-07","domenica",, "2022-08-08","lunedì",, "2022-08-09","martedì",,"https://ricette.giallozafferano.it/Insalata-di-pasta-Mediterranea.html" -"2022-08-10","mercoledì",, +"2022-08-10","mercoledì",,"https://ricette.giallozafferano.it/Insalata-con-uova-strapazzate.html" "2022-08-11","giovedì",,"https://ricette.giallozafferano.it/Verdure-gratinate-al-forno.html" -"2022-08-12","venerdì",, -"2022-08-13","sabato",, +"2022-08-12","venerdì",,"https://ricette.giallozafferano.it/Garganelli-con-pesto-di-zucchine-e-gamberetti.html" +"2022-08-13","sabato","https://ricette.giallozafferano.it/Insalata-di-bulgur-vegana.html", "2022-08-14","domenica",, "2022-08-15","lunedì",,"https://ricette.giallozafferano.it/Pasta-con-le-melanzane.html" -"2022-08-16","martedì",, +"2022-08-16","martedì",,"https://ricette.giallozafferano.it/Tempeh-alle-verdure.html" "2022-08-17","mercoledì",,"https://ricette.giallozafferano.it/Cocotte-di-quinoa.html" -"2022-08-18","giovedì",, -"2022-08-19","venerdì",, +"2022-08-18","giovedì",,"https://ricette.giallozafferano.it/Spaghetti-poveri.html" +"2022-08-19","venerdì",,"https://ricette.giallozafferano.it/Bocconcini-di-pollo-con-yogurt-e-curcuma.html" "2022-08-20","sabato",,"https://ricette.giallozafferano.it/Salmorejo.html" "2022-08-21","domenica",, -"2022-08-22","lunedì",, +"2022-08-22","lunedì",,"https://ricette.giallozafferano.it/Insalata-di-quinoa-alla-greca.html" "2022-08-23","martedì",, "2022-08-24","mercoledì",,"https://ricette.giallozafferano.it/Pasta-fredda-con-pesto-senz-aglio.html" "2022-08-25","giovedì",, -"2022-08-26","venerdì",, +"2022-08-26","venerdì",,"https://ricette.giallozafferano.it/Spiedini-di-pollo.html" "2022-08-27","sabato","https://ricette.giallozafferano.it/Orata-al-forno.html", "2022-08-28","domenica",, "2022-08-29","lunedì",, -"2022-08-30","martedì",, -"2022-08-31","mercoledì",, +"2022-08-30","martedì",,"https://ricette.giallozafferano.it/Scaloppine-saporite-con-cotto-e-formaggio.html" +"2022-08-31","mercoledì",,"https://ricette.giallozafferano.it/Tempeh-alle-verdure.html" "2022-09-01","giovedì",, "2022-09-02","venerdì",,"https://ricette.giallozafferano.it/Petto-di-pollo-ai-peperoni.html" "2022-09-03","sabato",, @@ -250,8 +250,8 @@ "2022-09-06","martedì",, "2022-09-07","mercoledì",, "2022-09-08","giovedì",,"https://ricette.giallozafferano.it/Pasta-con-le-melanzane.html" -"2022-09-09","venerdì",, -"2022-09-10","sabato",, +"2022-09-09","venerdì",,"https://ricette.giallozafferano.it/Spaghetti-di-riso-con-carne-e-verdure.html" +"2022-09-10","sabato","https://ricette.giallozafferano.it/Maccheroncini-al-fume.html", "2022-09-11","domenica","https://ricette.giallozafferano.it/Polpo-alla-Luciana.html", "2022-09-12","lunedì",,"https://ricette.giallozafferano.it/Pennette-con-speck-e-zucchine.html" "2022-09-13","martedì",, @@ -270,7 +270,7 @@ "2022-09-26","lunedì",,"https://ricette.giallozafferano.it/Mezze-maniche-al-tonno.html" "2022-09-27","martedì",, "2022-09-28","mercoledì",,"https://ricette.giallozafferano.it/Orata-al-forno.html" -"2022-09-29","giovedì",, +"2022-09-29","giovedì",,"https://ricette.giallozafferano.it/Pasta-con-crema-di-peperoni.html" "2022-09-30","venerdì",, "2022-10-01","sabato",, "2022-10-02","domenica","https://ricette.giallozafferano.it/Gnocchi-alla-sorrentina.html", @@ -279,23 +279,23 @@ "2022-10-05","mercoledì",, "2022-10-06","giovedì",,"https://ricette.giallozafferano.it/Saltimbocca-alla-Romana.html" "2022-10-07","venerdì",,"https://ricette.giallozafferano.it/Risotto-ai-funghi.html" -"2022-10-08","sabato","https://ricette.giallozafferano.it/Torta-Pasqualina.html", +"2022-10-08","sabato","https://ricette.giallozafferano.it/Torta-Pasqualina.html","https://www.chefkoch.de/rezepte/1643661271940496/Ukrainischer-Borschtsch.html" "2022-10-09","domenica",, "2022-10-10","lunedì",,"https://ricette.giallozafferano.it/Pennette-con-speck-e-zucchine.html" "2022-10-11","martedì",, "2022-10-12","mercoledì",, -"2022-10-13","giovedì",, +"2022-10-13","giovedì",,"https://ricette.giallozafferano.it/Maccheroncini-al-fume.html" "2022-10-14","venerdì",,"https://ricette.giallozafferano.it/Polpette-al-sugo.html" -"2022-10-15","sabato",, +"2022-10-15","sabato",,"https://ricette.giallozafferano.it/Ratatouille.html" "2022-10-16","domenica",, "2022-10-17","lunedì",, "2022-10-18","martedì",, "2022-10-19","mercoledì",,"https://ricette.giallozafferano.it/Scaloppine-ai-funghi.html" "2022-10-20","giovedì",, "2022-10-21","venerdì",, -"2022-10-22","sabato","https://ricette.giallozafferano.it/Gnudi.html", +"2022-10-22","sabato","https://ricette.giallozafferano.it/Gnudi.html","https://ricette.giallozafferano.it/Peperoni-ripieni-di-carne-e-salsiccia.html" "2022-10-23","domenica",, -"2022-10-24","lunedì",, +"2022-10-24","lunedì",,"https://ricette.giallozafferano.it/Cordon-bleu-di-zucca.html" "2022-10-25","martedì",, "2022-10-26","mercoledì",, "2022-10-27","giovedì",, @@ -305,7 +305,7 @@ "2022-10-31","lunedì",, "2022-11-01","martedì",, "2022-11-02","mercoledì",, -"2022-11-03","giovedì",, +"2022-11-03","giovedì",,"https://ricette.giallozafferano.it/Involtini-di-cotoletta.html" "2022-11-04","venerdì",, "2022-11-05","sabato","https://ricette.giallozafferano.it/Spatzle-di-spinaci.html", "2022-11-06","domenica",, @@ -321,25 +321,25 @@ "2022-11-16","mercoledì",, "2022-11-17","giovedì",, "2022-11-18","venerdì",,"https://ricette.giallozafferano.it/Torta-rustica.html" -"2022-11-19","sabato",, +"2022-11-19","sabato",,"https://ricette.giallozafferano.it/Ragu-di-seitan.html" "2022-11-20","domenica",, "2022-11-21","lunedì",, -"2022-11-22","martedì",, +"2022-11-22","martedì",,"https://ricette.giallozafferano.it/Cordon-bleu-di-zucca.html" "2022-11-23","mercoledì",, "2022-11-24","giovedì",, "2022-11-25","venerdì",,"https://ricette.giallozafferano.it/Vellutata-di-zucca-e-carote.html" -"2022-11-26","sabato","https://ricette.giallozafferano.it/Orata-al-forno.html", +"2022-11-26","sabato","https://ricette.giallozafferano.it/Orata-al-forno.html","https://www.chefkoch.de/rezepte/1643661271940496/Ukrainischer-Borschtsch.html" "2022-11-27","domenica",, "2022-11-28","lunedì",, "2022-11-29","martedì",,"https://ricette.giallozafferano.it/Scaloppine-ai-funghi.html" "2022-11-30","mercoledì",, "2022-12-01","giovedì",, -"2022-12-02","venerdì",, -"2022-12-03","sabato",, +"2022-12-02","venerdì",,"https://ricette.giallozafferano.it/Polpette-di-spinaci-e-ricotta.html" +"2022-12-03","sabato",,"https://ricette.giallozafferano.it/Spezzatino-alla-Guinness.html" "2022-12-04","domenica",, "2022-12-05","lunedì",,"https://ricette.giallozafferano.it/Spatzle-di-spinaci.html" "2022-12-06","martedì",, -"2022-12-07","mercoledì",, +"2022-12-07","mercoledì",,"https://ricette.giallozafferano.it/Involtini-di-cotoletta.html" "2022-12-08","giovedì",, "2022-12-09","venerdì",, "2022-12-10","sabato","https://ricette.giallozafferano.it/Gnudi.html", @@ -349,7 +349,7 @@ "2022-12-14","mercoledì",,"https://ricette.giallozafferano.it/Risotto-ai-funghi.html" "2022-12-15","giovedì",,"https://ricette.giallozafferano.it/Vellutata-di-porri-con-crostini-saporiti.html" "2022-12-16","venerdì",, -"2022-12-17","sabato",, +"2022-12-17","sabato",,"https://ricette.giallozafferano.it/Pasticcio-di-zucca.html" "2022-12-18","domenica","https://ricette.giallozafferano.it/Polpette-al-sugo.html", "2022-12-19","lunedì",, "2022-12-20","martedì",, diff --git a/src/api_client.rs b/src/api_client.rs index 210d054..b17d0a3 100644 --- a/src/api_client.rs +++ b/src/api_client.rs @@ -64,8 +64,26 @@ impl ApiClient { }) } - pub fn rest(&self) -> &reqwest::Client { - &self.rest + pub async fn rest<'a, F, R>(&'a self, submitter: F) -> R::Output + where + F: Fn(&'a reqwest::Client) -> R, + R: std::future::Future>, + { + let _ = self.rest_semaphore.acquire().await.unwrap(); + let mut retries = 0; + loop { + let result: R::Output = submitter(&self.rest).await; + + match result { + Ok(response) => break Ok(response), + Err(_) if retries < 10 => { + retries += 1; + std::thread::sleep(retries * std::time::Duration::from_millis(500)); + continue; + } + err => break err, + } + } } pub fn base_url(&self) -> &Url { @@ -91,20 +109,21 @@ impl ApiClient { { let report_method = reqwest::Method::from_bytes(b"REPORT").unwrap(); let events_xml = self - .rest() - .request( - report_method, - // TODO extract into helper method - self.caldav_base_url.join(&format!( - "calendars/{}/{}", - self.username(), - calendar_name.to_lowercase().replace(" ", "-") - ))?, - ) - .header("Prefer", "return-minimal") - .header("Content-Type", "application/xml; charset=utf-8") - .header("Depth", 1) - .body(format!( + .rest(|client| async { + let response = client + .request( + report_method.clone(), + // TODO extract into helper method + self.caldav_base_url.join(&format!( + "calendars/{}/{}", + self.username(), + calendar_name.to_lowercase().replace(" ", "-") + ))?, + ) + .header("Prefer", "return-minimal") + .header("Content-Type", "application/xml; charset=utf-8") + .header("Depth", 1) + .body(format!( " @@ -135,7 +154,10 @@ impl ApiClient { .format(constants::ICAL_UTCTIME_FMT) .to_string() )) - .send() + .send() + .await; + Ok(response?) + }) .await? .text() .await?; diff --git a/src/commands/groceries.rs b/src/commands/groceries.rs index ee52dd9..ba7643c 100644 --- a/src/commands/groceries.rs +++ b/src/commands/groceries.rs @@ -63,9 +63,12 @@ where // TODO code duplicated with schedule_csv::get_all_recipes let recipe_url = format!("apps/cookbook/api/recipes/{id}"); let response = api_client - .rest() - .get(api_client.base_url().join(&recipe_url).unwrap()) - .send() + .rest(|client| async { + Ok(client + .get(api_client.base_url().join(&recipe_url).unwrap()) + .send() + .await?) + }) .await .expect(&format!("Cannot fetch recipe with id {}", id)); @@ -119,9 +122,13 @@ async fn save_grocery_list(api_client: &ApiClient, filename: &str, contents: &st .and_then(|url| { futures::executor::block_on(async { let response = api_client - .rest() - .request(Method::from_bytes(b"MKCOL").unwrap(), url.clone()) - .send() + .rest(|client| async { + let r = client + .request(Method::from_bytes(b"MKCOL").unwrap(), url.clone()) + .send() + .await; + Ok(r?) + }) .await; match response.map(|r| r.status()) { @@ -141,11 +148,15 @@ async fn save_grocery_list(api_client: &ApiClient, filename: &str, contents: &st let file_url = dav_base_url.join(filename).unwrap(); log::info!("Saving grocery list to {}", &file_url); let response = api_client - .rest() - .put(file_url.clone()) - .header("Content-Type", "text/markdown; charset=utf-8") - .body(contents.to_owned()) - .send() + .rest(|client| async { + let r = client + .put(file_url.clone()) + .header("Content-Type", "text/markdown; charset=utf-8") + .body(contents.to_owned()) + .send() + .await; + Ok(r?) + }) .await?; match response.status() { diff --git a/src/commands/import.rs b/src/commands/import.rs index 347dbb2..ebf61c4 100644 --- a/src/commands/import.rs +++ b/src/commands/import.rs @@ -10,12 +10,16 @@ where { for url in urls { let response = api_client - .rest() - .post(api_client.base_url().join("apps/cookbook/import")?) - .json(&serde_json::json!({ - "url": url.as_ref(), - })) - .send() + .rest(|client| async { + let r = client + .post(api_client.base_url().join("apps/cookbook/import")?) + .json(&serde_json::json!({ + "url": url.as_ref(), + })) + .send() + .await; + Ok(r?) + }) .await?; if ![StatusCode::OK, StatusCode::CONFLICT].contains(&response.status()) { anyhow::bail!( diff --git a/src/commands/purge.rs b/src/commands/purge.rs index 099e353..6c859e5 100644 --- a/src/commands/purge.rs +++ b/src/commands/purge.rs @@ -4,23 +4,24 @@ use {crate::api_client::ApiClient, crate::constants, anyhow::Result, reqwest::Method}; pub async fn with(api_client: &ApiClient, calendar_name: &str) -> Result<()> { - let report_method = Method::from_bytes(b"REPORT")?; + let report_method: Method = Method::from_bytes(b"REPORT")?; let events_xml = api_client - .rest() - .request( - report_method, - // TODO extract into helper method - api_client.caldav_base_url().join(&format!( - "calendars/{}/{}/", - api_client.username(), - calendar_name.to_lowercase().replace(" ", "-") - ))?, - ) - .header("Prefer", "return-minimal") - .header("Content-Type", "application/xml; charset=utf-8") - .header("Depth", 1) - .body(format!( - " + .rest(|client| async { + let response = client + .request( + report_method.clone(), + // TODO extract into helper method + api_client.caldav_base_url().join(&format!( + "calendars/{}/{}/", + api_client.username(), + calendar_name.to_lowercase().replace(" ", "-") + ))?, + ) + .header("Prefer", "return-minimal") + .header("Content-Type", "application/xml; charset=utf-8") + .header("Depth", 1) + .body(format!( + " @@ -33,9 +34,12 @@ pub async fn with(api_client: &ApiClient, calendar_name: &str) -> Result<()> { ", - constants::CALENDAR_PROVIDER, - )) - .send() + constants::CALENDAR_PROVIDER, + )) + .send() + .await; + Ok(response?) + }) .await? .text() .await?; @@ -52,9 +56,12 @@ pub async fn with(api_client: &ApiClient, calendar_name: &str) -> Result<()> { for url in events_to_purge { api_client - .rest() - .delete(api_client.base_url().join(&url)?) - .send() + .rest(|client| async { + Ok(client + .delete(api_client.base_url().join(&url)?) + .send() + .await?) + }) .await?; log::debug!("Purged {}", &url); } diff --git a/src/commands/schedule.rs b/src/commands/schedule.rs index 529b660..120b8de 100644 --- a/src/commands/schedule.rs +++ b/src/commands/schedule.rs @@ -5,9 +5,13 @@ use {crate::api_client::ApiClient, crate::recipe, anyhow::Result}; pub async fn with(api_client: &ApiClient) -> Result<()> { let recipes = api_client - .rest() - .get(api_client.base_url().join("apps/cookbook/api/recipes")?) - .send() + .rest(|client| async { + let response = client + .get(api_client.base_url().join("apps/cookbook/api/recipes")?) + .send() + .await; + Ok(response?) + }) .await?; println!("{:#?}", recipes.json::>().await?); todo!(); diff --git a/src/commands/schedule_csv.rs b/src/commands/schedule_csv.rs index a1ae949..d86c76b 100644 --- a/src/commands/schedule_csv.rs +++ b/src/commands/schedule_csv.rs @@ -81,30 +81,53 @@ where async fn get_all_recipes(api_client: &ApiClient) -> Result>> { log::info!("Getting list of all recipes"); let metadata = api_client - .rest() - .get(api_client.base_url().join("apps/cookbook/api/recipes")?) - .send() + .rest(|client| async { + let response = client + .get(api_client.base_url().join("apps/cookbook/api/recipes")?) + .send() + .await; + Ok(response?) + }) .await? .json::>() .await?; let recipes = metadata.iter().map(|rm| async { - let response = api_client - .rest() - .get( - api_client - .base_url() - .join(&format!("apps/cookbook/api/recipes/{id}", id = rm.id)) - .unwrap(), - ) - .send() - .await - .expect(&format!( - "Cannot fetch recipe {} with id {}", - rm.name, rm.id - )); + // TODO: wrap this, heavily refactor this mess + let _ = api_client.rest_semaphore.acquire().await.unwrap(); + let mut retries = 0; + let response = loop { + let result = api_client + .rest(|client| async { + let response = client + .get( + api_client + .base_url() + .join(&format!("apps/cookbook/api/recipes/{id}", id = rm.id)) + .unwrap(), + ) + .send() + .await; + Ok(response?) + }) + .await; - response.json::().await.map(|r| Rc::new(r)) + match result { + Ok(response) => break response, + Err(_) if retries < 10 => { + retries += 1; + std::thread::sleep(retries * std::time::Duration::from_millis(500)); + continue; + } + _ => bail!("Cannot fetch recipe {} with id {}", rm.name, rm.id), + } + }; + + response + .json::() + .await + .map(|r| Rc::new(r)) + .map_err(|err| anyhow::anyhow!(err)) }); let recipes = try_join_all(recipes).await?; @@ -180,20 +203,19 @@ where 1, ); - // TODO: wrap this - let _ = api_client.rest_semaphore.acquire().await.unwrap(); let response = api_client - .rest() - .put(url) - .header("Content-Type", "text/calendar; charset=utf-8") - .body(cal_as_string) - .send() + .rest(|client| async { + let response = client + .put(url.clone()) + .header("Content-Type", "text/calendar; charset=utf-8") + .body(cal_as_string.clone()) + .send() + .await; + Ok(response?) + }) .await; log::info!("{}", info_message); - - // TODO: magic numbers are bad... - std::thread::sleep(std::time::Duration::from_millis(300)); response });