From 13608bc41ec887c214e1bcfc2242ff8dc0ddf5b9 Mon Sep 17 00:00:00 2001 From: Per Stark Date: Thu, 19 Dec 2024 23:15:12 +0100 Subject: [PATCH] refactoring: new structure and mailer --- Cargo.lock | 619 ++++++++++++------ Cargo.toml | 2 +- assets/style.css | 98 +++ src/bin/server.rs | 19 +- src/retrieval/mod.rs | 2 + .../helper.rs => retrieval/query_helper.rs} | 19 +- .../query_helper_prompt.rs} | 0 src/server/routes/{ => api}/file.rs | 0 src/server/routes/{ => api}/ingress.rs | 0 src/server/routes/api/mod.rs | 4 + src/server/routes/{ => api}/query.rs | 22 +- src/server/routes/{ => api}/queue_length.rs | 0 src/server/routes/{ => html}/auth.rs | 13 +- src/server/routes/{ => html}/index.rs | 25 +- src/server/routes/html/mod.rs | 55 ++ src/server/routes/{ => html}/search_result.rs | 5 +- src/server/routes/mod.rs | 49 +- src/utils/mailer.rs | 23 + src/utils/mod.rs | 1 + templates/auth/signup.html | 0 templates/auth/signup_form.html | 33 +- templates/base_template.html | 14 - templates/full_body_template.html | 28 - templates/index.html | 2 +- todo.md | 5 +- 25 files changed, 659 insertions(+), 379 deletions(-) rename src/{server/routes/query/helper.rs => retrieval/query_helper.rs} (93%) rename src/{server/routes/query/prompt.rs => retrieval/query_helper_prompt.rs} (100%) rename src/server/routes/{ => api}/file.rs (100%) rename src/server/routes/{ => api}/ingress.rs (100%) create mode 100644 src/server/routes/api/mod.rs rename src/server/routes/{ => api}/query.rs (64%) rename src/server/routes/{ => api}/queue_length.rs (100%) rename src/server/routes/{ => html}/auth.rs (80%) rename src/server/routes/{ => html}/index.rs (56%) create mode 100644 src/server/routes/html/mod.rs rename src/server/routes/{ => html}/search_result.rs (89%) create mode 100644 src/utils/mailer.rs delete mode 100644 templates/auth/signup.html delete mode 100644 templates/base_template.html delete mode 100644 templates/full_body_template.html diff --git a/Cargo.lock b/Cargo.lock index b9eda87..f125d68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -999,16 +999,6 @@ dependencies = [ "syn_derive", ] -[[package]] -name = "bstr" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "bumpalo" version = "3.16.0" @@ -1170,25 +1160,13 @@ dependencies = [ ] [[package]] -name = "chrono-tz" -version = "0.9.0" +name = "chumsky" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb" +checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9" dependencies = [ - "chrono", - "chrono-tz-build", - "phf", -] - -[[package]] -name = "chrono-tz-build" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1" -dependencies = [ - "parse-zoneinfo", - "phf", - "phf_codegen", + "hashbrown 0.14.5", + "stacker", ] [[package]] @@ -1307,25 +1285,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.20" @@ -1611,6 +1570,22 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "email-encoding" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea3d894bbbab314476b265f9b2d46bf24b123a36dd0e96b06a1b49545b9d9dcc" +dependencies = [ + "base64 0.22.1", + "memchr", +] + +[[package]] +name = "email_address" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449" + [[package]] name = "ena" version = "0.14.3" @@ -1760,6 +1735,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -2027,30 +2017,6 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" -[[package]] -name = "globset" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", -] - -[[package]] -name = "globwalk" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" -dependencies = [ - "bitflags 2.6.0", - "ignore", - "walkdir", -] - [[package]] name = "half" version = "2.4.1" @@ -2144,6 +2110,17 @@ dependencies = [ "digest", ] +[[package]] +name = "hostname" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" +dependencies = [ + "cfg-if", + "libc", + "windows", +] + [[package]] name = "html5ever" version = "0.27.0" @@ -2210,15 +2187,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "humansize" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" -dependencies = [ - "libm", -] - [[package]] name = "humantime" version = "2.1.0" @@ -2307,6 +2275,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -2324,19 +2410,24 @@ dependencies = [ ] [[package]] -name = "ignore" -version = "0.4.23" +name = "idna" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata 0.4.7", - "same-file", - "walkdir", - "winapi-util", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -2554,6 +2645,35 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lettre" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab4c9a167ff73df98a5ecc07e8bf5ce90b583665da3d1762eb1f775ad4d0d6f5" +dependencies = [ + "base64 0.22.1", + "chumsky", + "email-encoding", + "email_address", + "fastrand 2.1.1", + "futures-util", + "hostname", + "httpdate", + "idna 1.0.3", + "mime", + "native-tls", + "nom", + "percent-encoding", + "quoted_printable", + "rustls", + "rustls-pemfile", + "rustls-pki-types", + "socket2 0.5.7", + "tokio", + "url", + "webpki-roots", +] + [[package]] name = "lexicmp" version = "0.1.0" @@ -2610,6 +2730,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lock_api" version = "0.4.12" @@ -2839,6 +2965,23 @@ dependencies = [ "rand", ] +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "ndarray" version = "0.15.6" @@ -3051,12 +3194,50 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl" +version = "0.10.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "overload" version = "0.1.1" @@ -3114,15 +3295,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "parse-zoneinfo" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" -dependencies = [ - "regex", -] - [[package]] name = "password-hash" version = "0.5.0" @@ -3194,40 +3366,6 @@ dependencies = [ "ucd-trie", ] -[[package]] -name = "pest_derive" -version = "2.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "pest_meta" -version = "2.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f" -dependencies = [ - "once_cell", - "pest", - "sha2", -] - [[package]] name = "petgraph" version = "0.6.5" @@ -3412,6 +3550,12 @@ dependencies = [ "spki", ] +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + [[package]] name = "polling" version = "2.8.0" @@ -3648,6 +3792,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "quoted_printable" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "640c9bd8497b02465aeef5375144c26062e0dcd5939dfcbb0f5db76cb8c17c73" + [[package]] name = "radium" version = "0.7.0" @@ -4467,16 +4617,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "slug" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724" -dependencies = [ - "deunicode", - "wasm-bindgen", -] - [[package]] name = "smallvec" version = "1.13.2" @@ -4897,28 +5037,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "tera" -version = "1.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab9d851b45e865f178319da0abdbfe6acbc4328759ff18dafc3a41c16b4cd2ee" -dependencies = [ - "chrono", - "chrono-tz", - "globwalk", - "humansize", - "lazy_static", - "percent-encoding", - "pest", - "pest_derive", - "rand", - "regex", - "serde", - "serde_json", - "slug", - "unic-segment", -] - [[package]] name = "term" version = "0.7.0" @@ -5023,6 +5141,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -5334,56 +5462,6 @@ dependencies = [ "web-time", ] -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-segment" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" -dependencies = [ - "unic-ucd-segment", -] - -[[package]] -name = "unic-ucd-segment" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - [[package]] name = "unicase" version = "2.7.0" @@ -5471,7 +5549,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", - "idna", + "idna 0.5.0", "percent-encoding", "serde", ] @@ -5488,6 +5566,18 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "uuid" version = "1.10.0" @@ -5505,6 +5595,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" @@ -5695,6 +5791,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -5891,6 +5997,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "ws_stream_wasm" version = "0.7.4" @@ -5947,6 +6065,30 @@ dependencies = [ "time", ] +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -5968,12 +6110,55 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure", +] + [[package]] name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "zettle_db" version = "0.1.0" @@ -5988,6 +6173,7 @@ dependencies = [ "axum_typed_multipart", "futures", "lapin", + "lettre", "mime", "mime_guess", "minijinja", @@ -5998,7 +6184,6 @@ dependencies = [ "sha2", "surrealdb", "tempfile", - "tera", "text-splitter", "thiserror", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 8c56efc..0a1c640 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ axum_session_surreal = "0.2.1" axum_typed_multipart = "0.12.1" futures = "0.3.31" lapin = { version = "2.5.0", features = ["serde_json"] } +lettre = { version = "0.11.11", features = ["rustls-tls"] } mime = "0.3.17" mime_guess = "2.0.5" minijinja = { version = "2.5.0", features = ["loader", "multi_template"] } @@ -24,7 +25,6 @@ serde_json = "1.0.128" sha2 = "0.10.8" surrealdb = "2.0.4" tempfile = "3.12.0" -tera = "1.20.0" text-splitter = "0.18.1" thiserror = "1.0.63" tokio = { version = "1.40.0", features = ["full"] } diff --git a/assets/style.css b/assets/style.css index 5e99c32..8435e4d 100644 --- a/assets/style.css +++ b/assets/style.css @@ -1182,6 +1182,20 @@ html { padding-bottom: 0.5rem; } +.indicator { + position: relative; + display: inline-flex; + width: -moz-max-content; + width: max-content; +} + +.indicator :where(.indicator-item) { + z-index: 1; + position: absolute; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + white-space: nowrap; +} + .input { flex-shrink: 1; -webkit-appearance: none; @@ -1902,6 +1916,78 @@ html { width: 1.25rem; } +.indicator :where(.indicator-item) { + bottom: auto; + inset-inline-end: 0px; + inset-inline-start: auto; + top: 0px; + --tw-translate-y: -50%; + --tw-translate-x: 50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item):where([dir="rtl"], [dir="rtl"] *) { + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item.indicator-start) { + inset-inline-end: auto; + inset-inline-start: 0px; + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item.indicator-start):where([dir="rtl"], [dir="rtl"] *) { + --tw-translate-x: 50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item.indicator-center) { + inset-inline-end: 50%; + inset-inline-start: 50%; + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item.indicator-center):where([dir="rtl"], [dir="rtl"] *) { + --tw-translate-x: 50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item.indicator-end) { + inset-inline-end: 0px; + inset-inline-start: auto; + --tw-translate-x: 50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item.indicator-end):where([dir="rtl"], [dir="rtl"] *) { + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item.indicator-bottom) { + bottom: 0px; + top: auto; + --tw-translate-y: 50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item.indicator-middle) { + bottom: 50%; + top: 50%; + --tw-translate-y: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item.indicator-top) { + bottom: auto; + top: 0px; + --tw-translate-y: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + .menu-horizontal { display: inline-flex; flex-direction: row; @@ -1941,6 +2027,10 @@ html { box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } +.absolute { + position: absolute; +} + .mx-auto { margin-left: auto; margin-right: auto; @@ -1990,6 +2080,10 @@ html { min-height: 100vh; } +.min-h-full { + min-height: 100%; +} + .w-full { width: 100%; } @@ -2002,6 +2096,10 @@ html { max-width: 28rem; } +.max-w-lg { + max-width: 32rem; +} + .flex-1 { flex: 1 1 0%; } diff --git a/src/bin/server.rs b/src/bin/server.rs index e93f710..43b3d0a 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -19,17 +19,20 @@ use zettle_db::{ server::{ middleware_api_auth::api_auth, routes::{ - auth::{show_signup_form, signup_handler}, - file::upload_handler, - index::index_handler, - ingress::ingress_handler, - query::query_handler, - queue_length::queue_length_handler, - search_result::search_result_handler, + api::{ + file::upload_handler, ingress::ingress_handler, query::query_handler, + queue_length::queue_length_handler, + }, + html::{ + auth::{show_signup_form, signup_handler}, + index::index_handler, + search_result::search_result_handler, + }, }, AppState, }, storage::{db::SurrealDbClient, types::user::User}, + utils::mailer::Mailer, }; #[tokio::main(flavor = "multi_thread", worker_threads = 2)] @@ -59,6 +62,8 @@ async fn main() -> Result<(), Box> { Ok(env) }); + let mailer = Mailer::new(); + let app_state = AppState { rabbitmq_producer: Arc::new(RabbitMQProducer::new(&config).await?), rabbitmq_consumer: Arc::new(RabbitMQConsumer::new(&config, false).await?), diff --git a/src/retrieval/mod.rs b/src/retrieval/mod.rs index d9cde99..9a79d32 100644 --- a/src/retrieval/mod.rs +++ b/src/retrieval/mod.rs @@ -1,4 +1,6 @@ pub mod graph; +pub mod query_helper; +pub mod query_helper_prompt; pub mod vector; use crate::{ diff --git a/src/server/routes/query/helper.rs b/src/retrieval/query_helper.rs similarity index 93% rename from src/server/routes/query/helper.rs rename to src/retrieval/query_helper.rs index 525706a..1c83f19 100644 --- a/src/server/routes/query/helper.rs +++ b/src/retrieval/query_helper.rs @@ -3,6 +3,7 @@ use async_openai::types::{ CreateChatCompletionRequest, CreateChatCompletionRequestArgs, CreateChatCompletionResponse, ResponseFormat, ResponseFormatJsonSchema, }; +use serde::Deserialize; use serde_json::{json, Value}; use tracing::debug; @@ -12,10 +13,20 @@ use crate::{ storage::{db::SurrealDbClient, types::knowledge_entity::KnowledgeEntity}, }; -use super::{ - prompt::{get_query_response_schema, QUERY_SYSTEM_PROMPT}, - LLMResponseFormat, -}; +use super::query_helper_prompt::{get_query_response_schema, QUERY_SYSTEM_PROMPT}; + +#[derive(Debug, Deserialize)] +pub struct Reference { + #[allow(dead_code)] + pub reference: String, +} + +#[derive(Debug, Deserialize)] +pub struct LLMResponseFormat { + pub answer: String, + #[allow(dead_code)] + pub references: Vec, +} // /// Orchestrator function that takes a query and clients and returns a answer with references // /// diff --git a/src/server/routes/query/prompt.rs b/src/retrieval/query_helper_prompt.rs similarity index 100% rename from src/server/routes/query/prompt.rs rename to src/retrieval/query_helper_prompt.rs diff --git a/src/server/routes/file.rs b/src/server/routes/api/file.rs similarity index 100% rename from src/server/routes/file.rs rename to src/server/routes/api/file.rs diff --git a/src/server/routes/ingress.rs b/src/server/routes/api/ingress.rs similarity index 100% rename from src/server/routes/ingress.rs rename to src/server/routes/api/ingress.rs diff --git a/src/server/routes/api/mod.rs b/src/server/routes/api/mod.rs new file mode 100644 index 0000000..7403bb2 --- /dev/null +++ b/src/server/routes/api/mod.rs @@ -0,0 +1,4 @@ +pub mod file; +pub mod ingress; +pub mod query; +pub mod queue_length; diff --git a/src/server/routes/query.rs b/src/server/routes/api/query.rs similarity index 64% rename from src/server/routes/query.rs rename to src/server/routes/api/query.rs index c4ef0f3..5adaf0f 100644 --- a/src/server/routes/query.rs +++ b/src/server/routes/api/query.rs @@ -1,9 +1,8 @@ -pub mod helper; -pub mod prompt; - -use crate::{error::ApiError, server::AppState, storage::types::user::User}; +use crate::{ + error::ApiError, retrieval::query_helper::get_answer_with_references, server::AppState, + storage::types::user::User, +}; use axum::{extract::State, response::IntoResponse, Extension, Json}; -use helper::get_answer_with_references; use serde::Deserialize; use tracing::info; @@ -12,19 +11,6 @@ pub struct QueryInput { query: String, } -#[derive(Debug, Deserialize)] -pub struct Reference { - #[allow(dead_code)] - pub reference: String, -} - -#[derive(Debug, Deserialize)] -pub struct LLMResponseFormat { - pub answer: String, - #[allow(dead_code)] - pub references: Vec, -} - pub async fn query_handler( State(state): State, Extension(user): Extension, diff --git a/src/server/routes/queue_length.rs b/src/server/routes/api/queue_length.rs similarity index 100% rename from src/server/routes/queue_length.rs rename to src/server/routes/api/queue_length.rs diff --git a/src/server/routes/auth.rs b/src/server/routes/html/auth.rs similarity index 80% rename from src/server/routes/auth.rs rename to src/server/routes/html/auth.rs index c446a4c..c6f5ab2 100644 --- a/src/server/routes/auth.rs +++ b/src/server/routes/html/auth.rs @@ -1,7 +1,6 @@ use axum::{ extract::State, - http::Response, - response::{Html, IntoResponse}, + response::{IntoResponse, Redirect}, Form, }; use axum_htmx::HxBoosted; @@ -27,19 +26,23 @@ struct PageData { pub async fn show_signup_form( State(state): State, + auth: AuthSession, Surreal>, HxBoosted(boosted): HxBoosted, -) -> Result, ApiError> { +) -> Result { + if auth.is_authenticated() { + return Ok(Redirect::to("/").into_response()); + } let output = match boosted { true => render_block( "auth/signup_form.html", - "content", + "body", PageData {}, state.templates, )?, false => render_template("auth/signup_form.html", PageData {}, state.templates)?, }; - Ok(output) + Ok(output.into_response()) } pub async fn signup_handler( diff --git a/src/server/routes/index.rs b/src/server/routes/html/index.rs similarity index 56% rename from src/server/routes/index.rs rename to src/server/routes/html/index.rs index e37695d..96f78d2 100644 --- a/src/server/routes/index.rs +++ b/src/server/routes/html/index.rs @@ -1,24 +1,19 @@ use axum::{extract::State, response::Html}; use axum_session_auth::AuthSession; use axum_session_surreal::SessionSurrealPool; -use minijinja::context; -use serde::Serialize; -use serde_json::json; -use surrealdb::{engine::any::Any, sql::Relation, Surreal}; -use tera::Context; -// use tera::Context; +use surrealdb::{engine::any::Any, Surreal}; use tracing::info; use crate::{ error::ApiError, - server::{routes::render_template, AppState}, + page_data, + server::{routes::html::render_template, AppState}, storage::types::user::User, }; -#[derive(Serialize)] -struct PageData<'a> { - queue_length: &'a str, -} +page_data!(IndexData, { + queue_length: u32, +}); pub async fn index_handler( State(state): State, @@ -30,13 +25,7 @@ pub async fn index_handler( let queue_length = state.rabbitmq_consumer.get_queue_length().await?; - let output = render_template( - "index.html", - PageData { - queue_length: "1000", - }, - state.templates, - )?; + let output = render_template("index.html", IndexData { queue_length }, state.templates)?; Ok(output) } diff --git a/src/server/routes/html/mod.rs b/src/server/routes/html/mod.rs new file mode 100644 index 0000000..5600eff --- /dev/null +++ b/src/server/routes/html/mod.rs @@ -0,0 +1,55 @@ +use std::sync::Arc; + +use axum::response::Html; +use minijinja_autoreload::AutoReloader; + +pub mod auth; +pub mod index; +pub mod search_result; + +pub fn render_template( + template_name: &str, + context: T, + templates: Arc, +) -> Result, minijinja::Error> +where + T: serde::Serialize, +{ + let env = templates.acquire_env()?; + let tmpl = env.get_template(template_name)?; + + let context = minijinja::Value::from_serialize(&context); + let output = tmpl.render(context)?; + + Ok(output.into()) +} + +pub fn render_block( + template_name: &str, + block: &str, + context: T, + templates: Arc, +) -> Result, minijinja::Error> +where + T: serde::Serialize, +{ + let env = templates.acquire_env()?; + let tmpl = env.get_template(template_name)?; + + let context = minijinja::Value::from_serialize(&context); + let output = tmpl.eval_to_state(context)?.render_block(block)?; + + Ok(output.into()) +} + +#[macro_export] +macro_rules! page_data { + ($name:ident, {$($(#[$attr:meta])* $field:ident: $ty:ty),*$(,)?}) => { + use serde::{Serialize, Deserialize}; + + #[derive(Debug, Deserialize, Serialize)] + pub struct $name { + $($(#[$attr])* pub $field: $ty),* + } + }; +} diff --git a/src/server/routes/search_result.rs b/src/server/routes/html/search_result.rs similarity index 89% rename from src/server/routes/search_result.rs rename to src/server/routes/html/search_result.rs index 992a58f..fe7c658 100644 --- a/src/server/routes/search_result.rs +++ b/src/server/routes/html/search_result.rs @@ -5,14 +5,11 @@ use axum::{ use axum_session_auth::AuthSession; use axum_session_surreal::SessionSurrealPool; use serde::Deserialize; -use serde_json::json; use surrealdb::{engine::any::Any, Surreal}; -use tera::Context; use tracing::info; use crate::{ - error::ApiError, - server::{routes::query::helper::get_answer_with_references, AppState}, + error::ApiError, retrieval::query_helper::get_answer_with_references, server::AppState, storage::types::user::User, }; #[derive(Deserialize)] diff --git a/src/server/routes/mod.rs b/src/server/routes/mod.rs index 2be778b..bf4bec4 100644 --- a/src/server/routes/mod.rs +++ b/src/server/routes/mod.rs @@ -1,47 +1,2 @@ -use std::sync::Arc; - -use axum::response::Html; -use minijinja_autoreload::AutoReloader; - -pub mod auth; -pub mod file; -pub mod index; -pub mod ingress; -pub mod query; -pub mod queue_length; -pub mod search_result; - -pub fn render_template( - template_name: &str, - context: T, - templates: Arc, -) -> Result, minijinja::Error> -where - T: serde::Serialize, -{ - let env = templates.acquire_env()?; - let tmpl = env.get_template(template_name)?; - - let context = minijinja::Value::from_serialize(&context); - let output = tmpl.render(context)?; - - Ok(output.into()) -} - -pub fn render_block( - template_name: &str, - block: &str, - context: T, - templates: Arc, -) -> Result, minijinja::Error> -where - T: serde::Serialize, -{ - let env = templates.acquire_env()?; - let tmpl = env.get_template(template_name)?; - - let context = minijinja::Value::from_serialize(&context); - let output = tmpl.eval_to_state(context)?.render_block(block)?; - - Ok(output.into()) -} +pub mod api; +pub mod html; diff --git a/src/utils/mailer.rs b/src/utils/mailer.rs new file mode 100644 index 0000000..bdd3d7a --- /dev/null +++ b/src/utils/mailer.rs @@ -0,0 +1,23 @@ +use std::env; + +use lettre::{transport::smtp::authentication::Credentials, SmtpTransport}; + +pub struct Mailer { + pub mailer: SmtpTransport, +} + +impl Mailer { + pub fn new() -> Self { + let creds = Credentials::new( + env::var("SMTP_USERNAME").unwrap().to_owned(), + env::var("SMTP_PASSWORD").unwrap().to_owned(), + ); + + let mailer = SmtpTransport::relay(env::var("SMTP_RELAYER").unwrap().as_str()) + .unwrap() + .credentials(creds) + .build(); + + Mailer { mailer } + } +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 1768e8b..adc0132 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1 +1,2 @@ pub mod embedding; +pub mod mailer; diff --git a/templates/auth/signup.html b/templates/auth/signup.html deleted file mode 100644 index e69de29..0000000 diff --git a/templates/auth/signup_form.html b/templates/auth/signup_form.html index 956bc7d..1f0007e 100644 --- a/templates/auth/signup_form.html +++ b/templates/auth/signup_form.html @@ -1,10 +1,16 @@ -HELLO THIS IS OUTSIDE THE BLOCK -{% block content %} -
-
+{% extends "head_base.html" %} + +{% block body %} + +
+

Create your account

-
+
-
- -
OR
- -
- Already have an account? - Sign in -
+ +
OR
+ +
+ Already have an account? + Sign in +
{% endblock %} \ No newline at end of file diff --git a/templates/base_template.html b/templates/base_template.html deleted file mode 100644 index 6bb170e..0000000 --- a/templates/base_template.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - {% block title %}minnet{% endblock %} - - - {% block head %}{% endblock %} - -{% block body %}{% endblock %} - - \ No newline at end of file diff --git a/templates/full_body_template.html b/templates/full_body_template.html deleted file mode 100644 index ddf7df0..0000000 --- a/templates/full_body_template.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - -
- {% block content %}{% endblock %} -
- \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index 9de4d3a..5269fb7 100644 --- a/templates/index.html +++ b/templates/index.html @@ -5,7 +5,7 @@

- Welcome to Minnet + Welcome to minne

An experiment in creating a second brain diff --git a/todo.md b/todo.md index 9124ad1..5a4d980 100644 --- a/todo.md +++ b/todo.md @@ -1,3 +1,6 @@ \[x\] add user_id to ingress objects \[x\] restrict retrieval to users own objects -\[\] web frontend stuff +\[x\] templating +\[x\] redirects +\[\] hx-redirect +\[\] macro for pagedata?