refactoring: new structure and mailer

This commit is contained in:
Per Stark
2024-12-19 23:15:12 +01:00
parent 0a5e37130d
commit ff1c8836ee
25 changed files with 659 additions and 379 deletions

619
Cargo.lock generated
View File

@@ -999,16 +999,6 @@ dependencies = [
"syn_derive", "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]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.16.0" version = "3.16.0"
@@ -1170,25 +1160,13 @@ dependencies = [
] ]
[[package]] [[package]]
name = "chrono-tz" name = "chumsky"
version = "0.9.0" version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb" checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9"
dependencies = [ dependencies = [
"chrono", "hashbrown 0.14.5",
"chrono-tz-build", "stacker",
"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",
] ]
[[package]] [[package]]
@@ -1307,25 +1285,6 @@ dependencies = [
"libc", "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]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.20" version = "0.8.20"
@@ -1611,6 +1570,22 @@ version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 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]] [[package]]
name = "ena" name = "ena"
version = "0.14.3" version = "0.14.3"
@@ -1760,6 +1735,21 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 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]] [[package]]
name = "form_urlencoded" name = "form_urlencoded"
version = "1.2.1" version = "1.2.1"
@@ -2027,30 +2017,6 @@ version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" 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]] [[package]]
name = "half" name = "half"
version = "2.4.1" version = "2.4.1"
@@ -2144,6 +2110,17 @@ dependencies = [
"digest", "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]] [[package]]
name = "html5ever" name = "html5ever"
version = "0.27.0" version = "0.27.0"
@@ -2210,15 +2187,6 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "humansize"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7"
dependencies = [
"libm",
]
[[package]] [[package]]
name = "humantime" name = "humantime"
version = "2.1.0" version = "2.1.0"
@@ -2307,6 +2275,124 @@ dependencies = [
"cc", "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]] [[package]]
name = "ident_case" name = "ident_case"
version = "1.0.1" version = "1.0.1"
@@ -2324,19 +2410,24 @@ dependencies = [
] ]
[[package]] [[package]]
name = "ignore" name = "idna"
version = "0.4.23" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
dependencies = [ dependencies = [
"crossbeam-deque", "idna_adapter",
"globset", "smallvec",
"log", "utf8_iter",
"memchr", ]
"regex-automata 0.4.7",
"same-file", [[package]]
"walkdir", name = "idna_adapter"
"winapi-util", version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
dependencies = [
"icu_normalizer",
"icu_properties",
] ]
[[package]] [[package]]
@@ -2554,6 +2645,35 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 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]] [[package]]
name = "lexicmp" name = "lexicmp"
version = "0.1.0" version = "0.1.0"
@@ -2610,6 +2730,12 @@ version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "litemap"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.12" version = "0.4.12"
@@ -2839,6 +2965,23 @@ dependencies = [
"rand", "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]] [[package]]
name = "ndarray" name = "ndarray"
version = "0.15.6" version = "0.15.6"
@@ -3051,12 +3194,50 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" 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]] [[package]]
name = "openssl-probe" name = "openssl-probe"
version = "0.1.5" version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 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]] [[package]]
name = "overload" name = "overload"
version = "0.1.1" version = "0.1.1"
@@ -3114,15 +3295,6 @@ dependencies = [
"windows-targets 0.52.6", "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]] [[package]]
name = "password-hash" name = "password-hash"
version = "0.5.0" version = "0.5.0"
@@ -3194,40 +3366,6 @@ dependencies = [
"ucd-trie", "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]] [[package]]
name = "petgraph" name = "petgraph"
version = "0.6.5" version = "0.6.5"
@@ -3412,6 +3550,12 @@ dependencies = [
"spki", "spki",
] ]
[[package]]
name = "pkg-config"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]] [[package]]
name = "polling" name = "polling"
version = "2.8.0" version = "2.8.0"
@@ -3648,6 +3792,12 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "quoted_printable"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "640c9bd8497b02465aeef5375144c26062e0dcd5939dfcbb0f5db76cb8c17c73"
[[package]] [[package]]
name = "radium" name = "radium"
version = "0.7.0" version = "0.7.0"
@@ -4467,16 +4617,6 @@ dependencies = [
"autocfg", "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]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.13.2" version = "1.13.2"
@@ -4897,28 +5037,6 @@ dependencies = [
"utf-8", "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]] [[package]]
name = "term" name = "term"
version = "0.7.0" version = "0.7.0"
@@ -5023,6 +5141,16 @@ dependencies = [
"crunchy", "crunchy",
] ]
[[package]]
name = "tinystr"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
dependencies = [
"displaydoc",
"zerovec",
]
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.8.0" version = "1.8.0"
@@ -5334,56 +5462,6 @@ dependencies = [
"web-time", "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]] [[package]]
name = "unicase" name = "unicase"
version = "2.7.0" version = "2.7.0"
@@ -5471,7 +5549,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
dependencies = [ dependencies = [
"form_urlencoded", "form_urlencoded",
"idna", "idna 0.5.0",
"percent-encoding", "percent-encoding",
"serde", "serde",
] ]
@@ -5488,6 +5566,18 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 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]] [[package]]
name = "uuid" name = "uuid"
version = "1.10.0" version = "1.10.0"
@@ -5505,6 +5595,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.5" version = "0.9.5"
@@ -5695,6 +5791,16 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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]] [[package]]
name = "windows-core" name = "windows-core"
version = "0.52.0" version = "0.52.0"
@@ -5891,6 +5997,18 @@ dependencies = [
"memchr", "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]] [[package]]
name = "ws_stream_wasm" name = "ws_stream_wasm"
version = "0.7.4" version = "0.7.4"
@@ -5947,6 +6065,30 @@ dependencies = [
"time", "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]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.7.35" version = "0.7.35"
@@ -5968,12 +6110,55 @@ dependencies = [
"syn 2.0.87", "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]] [[package]]
name = "zeroize" name = "zeroize"
version = "1.8.1" version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 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]] [[package]]
name = "zettle_db" name = "zettle_db"
version = "0.1.0" version = "0.1.0"
@@ -5988,6 +6173,7 @@ dependencies = [
"axum_typed_multipart", "axum_typed_multipart",
"futures", "futures",
"lapin", "lapin",
"lettre",
"mime", "mime",
"mime_guess", "mime_guess",
"minijinja", "minijinja",
@@ -5998,7 +6184,6 @@ dependencies = [
"sha2", "sha2",
"surrealdb", "surrealdb",
"tempfile", "tempfile",
"tera",
"text-splitter", "text-splitter",
"thiserror", "thiserror",
"tokio", "tokio",

View File

@@ -14,6 +14,7 @@ axum_session_surreal = "0.2.1"
axum_typed_multipart = "0.12.1" axum_typed_multipart = "0.12.1"
futures = "0.3.31" futures = "0.3.31"
lapin = { version = "2.5.0", features = ["serde_json"] } lapin = { version = "2.5.0", features = ["serde_json"] }
lettre = { version = "0.11.11", features = ["rustls-tls"] }
mime = "0.3.17" mime = "0.3.17"
mime_guess = "2.0.5" mime_guess = "2.0.5"
minijinja = { version = "2.5.0", features = ["loader", "multi_template"] } minijinja = { version = "2.5.0", features = ["loader", "multi_template"] }
@@ -24,7 +25,6 @@ serde_json = "1.0.128"
sha2 = "0.10.8" sha2 = "0.10.8"
surrealdb = "2.0.4" surrealdb = "2.0.4"
tempfile = "3.12.0" tempfile = "3.12.0"
tera = "1.20.0"
text-splitter = "0.18.1" text-splitter = "0.18.1"
thiserror = "1.0.63" thiserror = "1.0.63"
tokio = { version = "1.40.0", features = ["full"] } tokio = { version = "1.40.0", features = ["full"] }

View File

@@ -1182,6 +1182,20 @@ html {
padding-bottom: 0.5rem; 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 { .input {
flex-shrink: 1; flex-shrink: 1;
-webkit-appearance: none; -webkit-appearance: none;
@@ -1902,6 +1916,78 @@ html {
width: 1.25rem; 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 { .menu-horizontal {
display: inline-flex; display: inline-flex;
flex-direction: row; 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); 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 { .mx-auto {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
@@ -1990,6 +2080,10 @@ html {
min-height: 100vh; min-height: 100vh;
} }
.min-h-full {
min-height: 100%;
}
.w-full { .w-full {
width: 100%; width: 100%;
} }
@@ -2002,6 +2096,10 @@ html {
max-width: 28rem; max-width: 28rem;
} }
.max-w-lg {
max-width: 32rem;
}
.flex-1 { .flex-1 {
flex: 1 1 0%; flex: 1 1 0%;
} }

View File

@@ -19,17 +19,20 @@ use zettle_db::{
server::{ server::{
middleware_api_auth::api_auth, middleware_api_auth::api_auth,
routes::{ routes::{
auth::{show_signup_form, signup_handler}, api::{
file::upload_handler, file::upload_handler, ingress::ingress_handler, query::query_handler,
index::index_handler, queue_length::queue_length_handler,
ingress::ingress_handler, },
query::query_handler, html::{
queue_length::queue_length_handler, auth::{show_signup_form, signup_handler},
search_result::search_result_handler, index::index_handler,
search_result::search_result_handler,
},
}, },
AppState, AppState,
}, },
storage::{db::SurrealDbClient, types::user::User}, storage::{db::SurrealDbClient, types::user::User},
utils::mailer::Mailer,
}; };
#[tokio::main(flavor = "multi_thread", worker_threads = 2)] #[tokio::main(flavor = "multi_thread", worker_threads = 2)]
@@ -59,6 +62,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(env) Ok(env)
}); });
let mailer = Mailer::new();
let app_state = AppState { let app_state = AppState {
rabbitmq_producer: Arc::new(RabbitMQProducer::new(&config).await?), rabbitmq_producer: Arc::new(RabbitMQProducer::new(&config).await?),
rabbitmq_consumer: Arc::new(RabbitMQConsumer::new(&config, false).await?), rabbitmq_consumer: Arc::new(RabbitMQConsumer::new(&config, false).await?),

View File

@@ -1,4 +1,6 @@
pub mod graph; pub mod graph;
pub mod query_helper;
pub mod query_helper_prompt;
pub mod vector; pub mod vector;
use crate::{ use crate::{

View File

@@ -3,6 +3,7 @@ use async_openai::types::{
CreateChatCompletionRequest, CreateChatCompletionRequestArgs, CreateChatCompletionResponse, CreateChatCompletionRequest, CreateChatCompletionRequestArgs, CreateChatCompletionResponse,
ResponseFormat, ResponseFormatJsonSchema, ResponseFormat, ResponseFormatJsonSchema,
}; };
use serde::Deserialize;
use serde_json::{json, Value}; use serde_json::{json, Value};
use tracing::debug; use tracing::debug;
@@ -12,10 +13,20 @@ use crate::{
storage::{db::SurrealDbClient, types::knowledge_entity::KnowledgeEntity}, storage::{db::SurrealDbClient, types::knowledge_entity::KnowledgeEntity},
}; };
use super::{ use super::query_helper_prompt::{get_query_response_schema, QUERY_SYSTEM_PROMPT};
prompt::{get_query_response_schema, QUERY_SYSTEM_PROMPT},
LLMResponseFormat, #[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<Reference>,
}
// /// Orchestrator function that takes a query and clients and returns a answer with references // /// Orchestrator function that takes a query and clients and returns a answer with references
// /// // ///

View File

@@ -0,0 +1,4 @@
pub mod file;
pub mod ingress;
pub mod query;
pub mod queue_length;

View File

@@ -1,9 +1,8 @@
pub mod helper; use crate::{
pub mod prompt; error::ApiError, retrieval::query_helper::get_answer_with_references, server::AppState,
storage::types::user::User,
use crate::{error::ApiError, server::AppState, storage::types::user::User}; };
use axum::{extract::State, response::IntoResponse, Extension, Json}; use axum::{extract::State, response::IntoResponse, Extension, Json};
use helper::get_answer_with_references;
use serde::Deserialize; use serde::Deserialize;
use tracing::info; use tracing::info;
@@ -12,19 +11,6 @@ pub struct QueryInput {
query: String, 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<Reference>,
}
pub async fn query_handler( pub async fn query_handler(
State(state): State<AppState>, State(state): State<AppState>,
Extension(user): Extension<User>, Extension(user): Extension<User>,

View File

@@ -1,7 +1,6 @@
use axum::{ use axum::{
extract::State, extract::State,
http::Response, response::{IntoResponse, Redirect},
response::{Html, IntoResponse},
Form, Form,
}; };
use axum_htmx::HxBoosted; use axum_htmx::HxBoosted;
@@ -27,19 +26,23 @@ struct PageData {
pub async fn show_signup_form( pub async fn show_signup_form(
State(state): State<AppState>, State(state): State<AppState>,
auth: AuthSession<User, String, SessionSurrealPool<Any>, Surreal<Any>>,
HxBoosted(boosted): HxBoosted, HxBoosted(boosted): HxBoosted,
) -> Result<Html<String>, ApiError> { ) -> Result<impl IntoResponse, ApiError> {
if auth.is_authenticated() {
return Ok(Redirect::to("/").into_response());
}
let output = match boosted { let output = match boosted {
true => render_block( true => render_block(
"auth/signup_form.html", "auth/signup_form.html",
"content", "body",
PageData {}, PageData {},
state.templates, state.templates,
)?, )?,
false => render_template("auth/signup_form.html", PageData {}, state.templates)?, false => render_template("auth/signup_form.html", PageData {}, state.templates)?,
}; };
Ok(output) Ok(output.into_response())
} }
pub async fn signup_handler( pub async fn signup_handler(

View File

@@ -1,24 +1,19 @@
use axum::{extract::State, response::Html}; use axum::{extract::State, response::Html};
use axum_session_auth::AuthSession; use axum_session_auth::AuthSession;
use axum_session_surreal::SessionSurrealPool; use axum_session_surreal::SessionSurrealPool;
use minijinja::context; use surrealdb::{engine::any::Any, Surreal};
use serde::Serialize;
use serde_json::json;
use surrealdb::{engine::any::Any, sql::Relation, Surreal};
use tera::Context;
// use tera::Context;
use tracing::info; use tracing::info;
use crate::{ use crate::{
error::ApiError, error::ApiError,
server::{routes::render_template, AppState}, page_data,
server::{routes::html::render_template, AppState},
storage::types::user::User, storage::types::user::User,
}; };
#[derive(Serialize)] page_data!(IndexData, {
struct PageData<'a> { queue_length: u32,
queue_length: &'a str, });
}
pub async fn index_handler( pub async fn index_handler(
State(state): State<AppState>, State(state): State<AppState>,
@@ -30,13 +25,7 @@ pub async fn index_handler(
let queue_length = state.rabbitmq_consumer.get_queue_length().await?; let queue_length = state.rabbitmq_consumer.get_queue_length().await?;
let output = render_template( let output = render_template("index.html", IndexData { queue_length }, state.templates)?;
"index.html",
PageData {
queue_length: "1000",
},
state.templates,
)?;
Ok(output) Ok(output)
} }

View File

@@ -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<T>(
template_name: &str,
context: T,
templates: Arc<AutoReloader>,
) -> Result<Html<String>, 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<T>(
template_name: &str,
block: &str,
context: T,
templates: Arc<AutoReloader>,
) -> Result<Html<String>, 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),*
}
};
}

View File

@@ -5,14 +5,11 @@ use axum::{
use axum_session_auth::AuthSession; use axum_session_auth::AuthSession;
use axum_session_surreal::SessionSurrealPool; use axum_session_surreal::SessionSurrealPool;
use serde::Deserialize; use serde::Deserialize;
use serde_json::json;
use surrealdb::{engine::any::Any, Surreal}; use surrealdb::{engine::any::Any, Surreal};
use tera::Context;
use tracing::info; use tracing::info;
use crate::{ use crate::{
error::ApiError, error::ApiError, retrieval::query_helper::get_answer_with_references, server::AppState,
server::{routes::query::helper::get_answer_with_references, AppState},
storage::types::user::User, storage::types::user::User,
}; };
#[derive(Deserialize)] #[derive(Deserialize)]

View File

@@ -1,47 +1,2 @@
use std::sync::Arc; pub mod api;
pub mod html;
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<T>(
template_name: &str,
context: T,
templates: Arc<AutoReloader>,
) -> Result<Html<String>, 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<T>(
template_name: &str,
block: &str,
context: T,
templates: Arc<AutoReloader>,
) -> Result<Html<String>, 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())
}

23
src/utils/mailer.rs Normal file
View File

@@ -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 }
}
}

View File

@@ -1 +1,2 @@
pub mod embedding; pub mod embedding;
pub mod mailer;

View File

@@ -1,10 +1,16 @@
HELLO THIS IS OUTSIDE THE BLOCK {% extends "head_base.html" %}
{% block content %}
<div class="max-h-full grid place-items-center place-content-center"> {% block body %}
<div class="max-w-md mx-auto"> <style>
form.htmx-request {
opacity: 0.5;
}
</style>
<div class="min-h-screen grid place-items-center place-content-center">
<div class="max-w-lg mx-auto">
<h2 class="text-2xl font-bold text-center mb-8">Create your account</h2> <h2 class="text-2xl font-bold text-center mb-8">Create your account</h2>
<form hx-post="/signup" hx-target="#signup-result" hx-indicator="#spinner" class="" psac-y-e6> <form hx-post="/signup" hx-target="#signup-result" class="">
<div class="form-control"> <div class="form-control">
<label class="label"> <label class="label">
<span class="label-text">Email</span> <span class="label-text">Email</span>
@@ -24,21 +30,20 @@ HELLO THIS IS OUTSIDE THE BLOCK
</div> </div>
<div class="form-control mt-6"> <div class="form-control mt-6">
<button class="btn btn-primary w-full"> <button id="submit-btn" class="btn btn-primary w-full">
Create Account Create Account
<span id="spinner" class="loading loading-spinner text-primary htmx-indicator"></span>
</button> </button>
</div> </div>
<div id="signup-result"></div> <div id="signup-result"></div>
<div class="divider">OR</div>
<div class="text-center text-sm">
Already have an account?
<a href="/signin" class="link link-primary">Sign in</a>
</div>
</form> </form>
<div class="divider">OR</div>
<div class="text-center text-sm">
Already have an account?
<a href="/signin" class="link link-primary">Sign in</a>
</div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -1,14 +0,0 @@
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}minnet{% endblock %}</title>
<script src="https://unpkg.com/htmx.org@1.9.2"></script>
<link rel="stylesheet" href="assets/style.css">
{% block head %}{% endblock %}
</head>
{% block body %}{% endblock %}
</html>

View File

@@ -1,28 +0,0 @@
<body class="min-h-screen">
<!-- Navbar -->
<nav class="navbar bg-base-200">
<div class="flex-1">
<a class="btn text-xl border-transparent btn-outline btn-primary" href="/">minnet</a>
</div>
<div class="flex-none">
<ul class="menu menu-horizontal px-1">
<li><a href="/signin">Login</a></li>
<li><a hx-boost="true" href="/signup">Sign up</a></li>
<li>
<details>
<summary>Parent</summary>
<ul class="bg-base-100 rounded-t-none p-2">
<li><a>Link 1</a></li>
<li><a>Link 2</a></li>
</ul>
</details>
</li>
</ul>
</div>
</nav>
<!-- Main Content -->
<main class="container mx-auto px-4 py-8">
{% block content %}{% endblock %}
</main>
</body>

View File

@@ -5,7 +5,7 @@
<div class="text-center space-y-4 mb-8"> <div class="text-center space-y-4 mb-8">
<h1 <h1
class="text-5xl font-bold bg-gradient-to-r from-blue-400 via-purple-500 to-pink-500 text-transparent bg-clip-text"> class="text-5xl font-bold bg-gradient-to-r from-blue-400 via-purple-500 to-pink-500 text-transparent bg-clip-text">
Welcome to Minnet Welcome to minne
</h1> </h1>
<p class="text-gray-400 text-xl"> <p class="text-gray-400 text-xl">
An experiment in creating a second brain An experiment in creating a second brain

View File

@@ -1,3 +1,6 @@
\[x\] add user_id to ingress objects \[x\] add user_id to ingress objects
\[x\] restrict retrieval to users own objects \[x\] restrict retrieval to users own objects
\[\] web frontend stuff \[x\] templating
\[x\] redirects
\[\] hx-redirect
\[\] macro for pagedata?