Compare commits
2 commits
85c6d4741f
...
cec5d50aa6
Author | SHA1 | Date | |
---|---|---|---|
cec5d50aa6 | |||
9d89154b23 |
10 changed files with 497 additions and 69 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +0,0 @@
|
||||||
[submodule "artwork"]
|
|
||||||
path = artwork
|
|
||||||
url = https://git.makerlab-murnau.de/MakerLab/artwork.git
|
|
279
Cargo.lock
generated
279
Cargo.lock
generated
|
@ -2,6 +2,12 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "adler32"
|
name = "adler32"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -17,6 +23,37 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "alloc-no-stdlib"
|
||||||
|
version = "2.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "alloc-stdlib"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
|
||||||
|
dependencies = [
|
||||||
|
"alloc-no-stdlib",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-compression"
|
||||||
|
version = "0.3.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a"
|
||||||
|
dependencies = [
|
||||||
|
"brotli",
|
||||||
|
"flate2",
|
||||||
|
"futures-core",
|
||||||
|
"memchr",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"zstd",
|
||||||
|
"zstd-safe",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.66"
|
version = "0.1.66"
|
||||||
|
@ -25,7 +62,7 @@ checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -84,6 +121,24 @@ dependencies = [
|
||||||
"tower-service",
|
"tower-service",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "axum-macros"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2bb524613be645939e280b7279f7b017f98cf7f5ef084ec374df373530e73277"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.15",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.20.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
|
@ -99,6 +154,27 @@ dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "brotli"
|
||||||
|
version = "3.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68"
|
||||||
|
dependencies = [
|
||||||
|
"alloc-no-stdlib",
|
||||||
|
"alloc-stdlib",
|
||||||
|
"brotli-decompressor",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "brotli-decompressor"
|
||||||
|
version = "2.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744"
|
||||||
|
dependencies = [
|
||||||
|
"alloc-no-stdlib",
|
||||||
|
"alloc-stdlib",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bstr"
|
name = "bstr"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
@ -129,6 +205,7 @@ checksum = "a8af54f5d48af1226928adc1f57edd22f5df1349e7da1fc96ae15cf43db0e871"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cairo-sys-rs",
|
"cairo-sys-rs",
|
||||||
|
"freetype-rs",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -144,6 +221,15 @@ dependencies = [
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.79"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||||
|
dependencies = [
|
||||||
|
"jobserver",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-expr"
|
name = "cfg-expr"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
|
@ -168,6 +254,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc32fast"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-common"
|
name = "crypto-common"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
|
@ -198,6 +293,16 @@ dependencies = [
|
||||||
"crypto-common",
|
"crypto-common",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flate2"
|
||||||
|
version = "1.0.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
|
||||||
|
dependencies = [
|
||||||
|
"crc32fast",
|
||||||
|
"miniz_oxide",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
|
@ -213,6 +318,27 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "freetype-rs"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d59c337e64822dd56a3a83ed75a662a470736bdb3a9fabfb588dff276b94a4e0"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"freetype-sys",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "freetype-sys"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "643148ca6cbad6bec384b52fbe1968547d578c4efe83109e035c43a71734ff88"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.27"
|
version = "0.3.27"
|
||||||
|
@ -228,6 +354,12 @@ version = "0.3.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd"
|
checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-sink"
|
||||||
|
version = "0.3.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.27"
|
version = "0.3.27"
|
||||||
|
@ -244,6 +376,7 @@ dependencies = [
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -367,12 +500,31 @@ dependencies = [
|
||||||
"adler32",
|
"adler32",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iri-string"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21859b667d66a4c1dacd9df0863b3efb65785474255face87f5bca39dd8407c0"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jobserver"
|
||||||
|
version = "0.1.26"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.140"
|
version = "0.2.140"
|
||||||
|
@ -403,6 +555,7 @@ name = "logo-generator"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
|
"axum-macros",
|
||||||
"cairo-rs",
|
"cairo-rs",
|
||||||
"mime_guess",
|
"mime_guess",
|
||||||
"png",
|
"png",
|
||||||
|
@ -411,6 +564,8 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tower-http",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -441,6 +596,15 @@ dependencies = [
|
||||||
"unicase",
|
"unicase",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
|
||||||
|
dependencies = [
|
||||||
|
"adler",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.8.6"
|
version = "0.8.6"
|
||||||
|
@ -545,7 +709,7 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -586,18 +750,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.51"
|
version = "1.0.56"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.23"
|
version = "1.0.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
@ -678,7 +842,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rust-embed-utils",
|
"rust-embed-utils",
|
||||||
"syn",
|
"syn 1.0.109",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -737,7 +901,7 @@ checksum = "4fc80d722935453bcafdc2c9a73cd6fac4dc1938f0346035d84bf99fa9e33217"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -792,6 +956,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slab"
|
||||||
|
version = "0.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
|
@ -819,6 +992,17 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sync_wrapper"
|
name = "sync_wrapper"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
@ -855,7 +1039,7 @@ checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -886,7 +1070,20 @@ checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-util"
|
||||||
|
version = "0.7.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -920,6 +1117,8 @@ 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 = "5d1d42a9b3f3ec46ba828e8d376aec14592ea199f70a06a548587ecd1c4ab658"
|
checksum = "5d1d42a9b3f3ec46ba828e8d376aec14592ea199f70a06a548587ecd1c4ab658"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-compression",
|
||||||
|
"base64",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
@ -927,10 +1126,19 @@ dependencies = [
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-range-header",
|
"http-range-header",
|
||||||
|
"httpdate",
|
||||||
|
"iri-string",
|
||||||
|
"mime",
|
||||||
|
"mime_guess",
|
||||||
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -954,9 +1162,21 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"log",
|
"log",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.30"
|
version = "0.1.30"
|
||||||
|
@ -993,6 +1213,15 @@ version = "1.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b55a3fef2a1e3b3a00ce878640918820d3c51081576ac657d23af9fc7928fdb"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version-compare"
|
name = "version-compare"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
@ -1128,3 +1357,33 @@ name = "windows_x86_64_msvc"
|
||||||
version = "0.42.1"
|
version = "0.42.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd"
|
||||||
|
version = "0.11.2+zstd.1.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
|
||||||
|
dependencies = [
|
||||||
|
"zstd-safe",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd-safe"
|
||||||
|
version = "5.0.2+zstd.1.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"zstd-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd-sys"
|
||||||
|
version = "2.0.8+zstd.1.5.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
|
@ -7,7 +7,7 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
png = "0.11.0"
|
png = "0.11.0"
|
||||||
cairo-rs = { version = "0.17.0", default-features = false, features = ["png"] }
|
cairo-rs = { version = "0.17.0", default-features = false, features = ["png", "svg", "freetype"] }
|
||||||
axum = "0.6.10"
|
axum = "0.6.10"
|
||||||
tokio = { version = "1.0", features = ["full"] }
|
tokio = { version = "1.0", features = ["full"] }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
@ -15,3 +15,6 @@ serde = { version = "1.0.152", features = ["derive"] }
|
||||||
rust-embed = { version = "6.6.0", features = ["include-exclude"] }
|
rust-embed = { version = "6.6.0", features = ["include-exclude"] }
|
||||||
mime_guess = "2.0.4"
|
mime_guess = "2.0.4"
|
||||||
serde_json = "1.0.94"
|
serde_json = "1.0.94"
|
||||||
|
axum-macros = "0.3.7"
|
||||||
|
tower-http = { version = "0.4.0", features = ["fs", "full"] }
|
||||||
|
tracing = "0.1.37"
|
||||||
|
|
1
artwork
1
artwork
|
@ -1 +0,0 @@
|
||||||
Subproject commit 13b39b2537350a24fe69a309e7f676a3c25f7bd0
|
|
BIN
fonts/Nunito-ExtraLight.ttf
Normal file
BIN
fonts/Nunito-ExtraLight.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-Light.ttf
Normal file
BIN
fonts/Nunito-Light.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-Regular.ttf
Normal file
BIN
fonts/Nunito-Regular.ttf
Normal file
Binary file not shown.
29
src/main.rs
29
src/main.rs
|
@ -1,20 +1,39 @@
|
||||||
use axum::Router;
|
use axum::{http::Request, response::Response, routing::get, Router};
|
||||||
use std::net::SocketAddr;
|
use std::{net::SocketAddr, time::Duration};
|
||||||
|
use text::EmbeddedFonts;
|
||||||
|
use tower_http::{catch_panic::CatchPanicLayer, trace::TraceLayer};
|
||||||
|
use tracing::Span;
|
||||||
|
|
||||||
mod color;
|
mod color;
|
||||||
mod polygon;
|
mod polygon;
|
||||||
mod routes;
|
mod routes;
|
||||||
|
mod text;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SharedState {}
|
pub struct SharedState {
|
||||||
|
fonts: EmbeddedFonts,
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let state = SharedState {};
|
let state = SharedState {
|
||||||
|
fonts: EmbeddedFonts::load(),
|
||||||
|
};
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.nest("/", routes::static_files::routes())
|
.nest("/", routes::static_files::routes())
|
||||||
.nest("/logo", routes::logo::routes())
|
.route("/logo.png", get(routes::logo::png))
|
||||||
|
.route("/logo.svg", get(routes::logo::svg))
|
||||||
.nest("/favicon.ico", routes::favicon::routes())
|
.nest("/favicon.ico", routes::favicon::routes())
|
||||||
|
.layer(
|
||||||
|
TraceLayer::new_for_http()
|
||||||
|
.on_request(|request: &Request<_>, _span: &Span| {
|
||||||
|
println!("Request {} {}", request.method(), request.uri());
|
||||||
|
})
|
||||||
|
.on_response(|response: &Response, latency: Duration, _span: &Span| {
|
||||||
|
println!("Response {}, {}ms", response.status(), latency.as_millis());
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.layer(CatchPanicLayer::new())
|
||||||
.with_state(state);
|
.with_state(state);
|
||||||
|
|
||||||
// run it
|
// run it
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
use axum::{extract::Query, routing::get, Router};
|
use std::time::Instant;
|
||||||
use cairo::{Context, Format, ImageSurface};
|
|
||||||
use rust_embed::RustEmbed;
|
use axum::{
|
||||||
|
extract::{Query, State},
|
||||||
|
routing::get,
|
||||||
|
Router,
|
||||||
|
};
|
||||||
|
use cairo::{freetype::Face, Context, FontFace, Format, ImageSurface, SvgSurface};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{polygon, SharedState};
|
use crate::{color::Color, polygon, text::DrawableText, SharedState};
|
||||||
|
|
||||||
#[derive(Deserialize, Default)]
|
#[derive(Deserialize, Default)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
@ -22,60 +27,39 @@ enum LogoOrientation {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Default)]
|
#[derive(Deserialize, Default)]
|
||||||
struct ImageProperties {
|
pub struct ImageProperties {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
variant: LogoVariant,
|
variant: LogoVariant,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
orientation: LogoOrientation,
|
orientation: LogoOrientation,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(RustEmbed)]
|
fn get_surface_size(properties: &ImageProperties) -> (i32, i32) {
|
||||||
#[folder = "artwork/logo"]
|
match (&properties.variant, &properties.orientation) {
|
||||||
#[include = "*_T.png"]
|
(LogoVariant::NoText, _) => (400, 400),
|
||||||
struct ImageFiles;
|
(_, LogoOrientation::Landscape) => (2127, 591),
|
||||||
|
(_, LogoOrientation::Portrait) => (1654, 1654),
|
||||||
fn get_surface_and_logo_coordiates(
|
|
||||||
properties: &ImageProperties,
|
|
||||||
) -> (ImageSurface, (f64, f64), f64, f64) {
|
|
||||||
if let LogoVariant::NoText = properties.variant {
|
|
||||||
return (
|
|
||||||
ImageSurface::create(Format::ARgb32, 400, 400).unwrap(),
|
|
||||||
(200.0, 200.0),
|
|
||||||
148.0,
|
|
||||||
67.0,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let background_image_path = match (&properties.variant, &properties.orientation) {
|
|
||||||
(LogoVariant::DarkText, LogoOrientation::Landscape) => "landscape/4C_T.png",
|
|
||||||
(LogoVariant::LightText, LogoOrientation::Landscape) => "landscape/W_T.png",
|
|
||||||
(LogoVariant::DarkText, LogoOrientation::Portrait) => "portrait/4C_T.png",
|
|
||||||
(LogoVariant::LightText, LogoOrientation::Portrait) => "portrait/W_T.png",
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let (coordinates, outer_radius, inner_radius) = match &properties.orientation {
|
|
||||||
LogoOrientation::Landscape => ((412.0, 299.0), 209.0, 99.0),
|
|
||||||
LogoOrientation::Portrait => ((828.0, 563.0), 253.0, 118.0),
|
|
||||||
};
|
|
||||||
|
|
||||||
let image = ImageFiles::get(background_image_path).unwrap();
|
|
||||||
(
|
|
||||||
ImageSurface::create_from_png(&mut image.data.as_ref()).unwrap(),
|
|
||||||
coordinates,
|
|
||||||
outer_radius,
|
|
||||||
inner_radius,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handler(Query(properties): Query<ImageProperties>) -> impl axum::response::IntoResponse {
|
fn create_image_surface(properties: &ImageProperties) -> ImageSurface {
|
||||||
let (surface, logo_coordinates, logo_outer_radius, logo_inner_radius) =
|
let (width, height) = get_surface_size(properties);
|
||||||
get_surface_and_logo_coordiates(&properties);
|
ImageSurface::create(Format::ARgb32, width, height).unwrap()
|
||||||
let context = Context::new(&surface).unwrap();
|
}
|
||||||
|
|
||||||
context.set_source_rgba(0.0, 0.0, 0.0, 0.0);
|
fn create_svg_surface(properties: &ImageProperties) -> SvgSurface {
|
||||||
|
let (width, height) = get_surface_size(properties);
|
||||||
|
|
||||||
context.paint().unwrap();
|
SvgSurface::new::<String>(width as f64, height as f64, None).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_logo(context: &Context, properties: &ImageProperties) {
|
||||||
|
let (logo_coordinates, logo_outer_radius, logo_inner_radius) =
|
||||||
|
match (&properties.variant, &properties.orientation) {
|
||||||
|
(LogoVariant::NoText, _) => ((200.0, 200.0), 148.0, 67.0),
|
||||||
|
(_, LogoOrientation::Landscape) => ((412.0, 299.0), 209.0, 99.0),
|
||||||
|
(_, LogoOrientation::Portrait) => ((828.0, 563.0), 253.0, 118.0),
|
||||||
|
};
|
||||||
|
|
||||||
polygon::draw_polygon_of_segmented_polygons(
|
polygon::draw_polygon_of_segmented_polygons(
|
||||||
logo_coordinates,
|
logo_coordinates,
|
||||||
|
@ -85,6 +69,81 @@ async fn handler(Query(properties): Query<ImageProperties>) -> impl axum::respon
|
||||||
&context,
|
&context,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_text(
|
||||||
|
context: &Context,
|
||||||
|
font_regular: &Face,
|
||||||
|
font_light: &Face,
|
||||||
|
properties: &ImageProperties,
|
||||||
|
) {
|
||||||
|
if let LogoVariant::NoText = properties.variant {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let color = match &properties.variant {
|
||||||
|
LogoVariant::DarkText => Color::from("#383F50"),
|
||||||
|
LogoVariant::LightText => Color::from("#ffffff"),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
context.set_source_rgb(
|
||||||
|
color.r as f64 / 255.0,
|
||||||
|
color.g as f64 / 255.0,
|
||||||
|
color.b as f64 / 255.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
let texts = match &properties.orientation {
|
||||||
|
LogoOrientation::Landscape => (
|
||||||
|
DrawableText {
|
||||||
|
position: (760.0, 356.0),
|
||||||
|
size: 228.0,
|
||||||
|
spacing: 45.5,
|
||||||
|
text: "makerlab",
|
||||||
|
},
|
||||||
|
DrawableText {
|
||||||
|
position: (1495.0, 504.0),
|
||||||
|
size: 110.0,
|
||||||
|
spacing: 10.5,
|
||||||
|
text: "MURNAU",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
LogoOrientation::Portrait => (
|
||||||
|
DrawableText {
|
||||||
|
position: (48.0, 1242.0),
|
||||||
|
size: 280.0,
|
||||||
|
spacing: 53.5,
|
||||||
|
text: "makerlab",
|
||||||
|
},
|
||||||
|
DrawableText {
|
||||||
|
position: (493.0, 1424.0),
|
||||||
|
size: 135.0,
|
||||||
|
spacing: 13.0,
|
||||||
|
text: "MURNAU",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
context.set_font_face(&FontFace::create_from_ft(font_regular).unwrap());
|
||||||
|
texts.0.draw(&context);
|
||||||
|
|
||||||
|
context.set_font_face(&FontFace::create_from_ft(font_light).unwrap());
|
||||||
|
texts.1.draw(&context);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[axum_macros::debug_handler]
|
||||||
|
pub async fn png(
|
||||||
|
Query(properties): Query<ImageProperties>,
|
||||||
|
State(state): State<SharedState>,
|
||||||
|
) -> impl axum::response::IntoResponse {
|
||||||
|
let (font_regular, font_light) = state.fonts.get().await;
|
||||||
|
|
||||||
|
// cannot use await after this, because surface does not implement Send
|
||||||
|
let surface = create_image_surface(&properties);
|
||||||
|
let context = Context::new(&surface).unwrap();
|
||||||
|
|
||||||
|
draw_logo(&context, &properties);
|
||||||
|
draw_text(&context, &font_regular, &font_light, &properties);
|
||||||
|
|
||||||
let mut data: Vec<u8> = Vec::new();
|
let mut data: Vec<u8> = Vec::new();
|
||||||
surface.write_to_png(&mut data).unwrap();
|
surface.write_to_png(&mut data).unwrap();
|
||||||
|
@ -95,6 +154,24 @@ async fn handler(Query(properties): Query<ImageProperties>) -> impl axum::respon
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn routes() -> Router<SharedState> {
|
#[axum_macros::debug_handler]
|
||||||
Router::new().route("/", get(handler))
|
pub async fn svg(
|
||||||
|
Query(properties): Query<ImageProperties>,
|
||||||
|
State(state): State<SharedState>,
|
||||||
|
) -> impl axum::response::IntoResponse {
|
||||||
|
let (font_regular, font_light) = state.fonts.get().await;
|
||||||
|
|
||||||
|
// cannot use await after this, because surface does not implement Send
|
||||||
|
let surface = create_svg_surface(&properties);
|
||||||
|
let context = Context::new(&surface).unwrap();
|
||||||
|
|
||||||
|
draw_logo(&context, &properties);
|
||||||
|
draw_text(&context, &font_regular, &font_light, &properties);
|
||||||
|
|
||||||
|
let mut data: Vec<u8> = Vec::new();
|
||||||
|
surface.write_to_png(&mut data).unwrap();
|
||||||
|
(
|
||||||
|
axum::response::AppendHeaders([(axum::http::header::CONTENT_TYPE, "image/png")]),
|
||||||
|
data,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
74
src/text.rs
Normal file
74
src/text.rs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use cairo::{
|
||||||
|
freetype::{Face, Library},
|
||||||
|
Context,
|
||||||
|
};
|
||||||
|
use rust_embed::RustEmbed;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
|
#[derive(RustEmbed)]
|
||||||
|
#[folder = "fonts"]
|
||||||
|
struct FontFiles;
|
||||||
|
|
||||||
|
struct InternalFonts {
|
||||||
|
light: Face,
|
||||||
|
regular: Face,
|
||||||
|
}
|
||||||
|
unsafe impl Send for InternalFonts {}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct EmbeddedFonts {
|
||||||
|
fonts: Arc<Mutex<InternalFonts>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EmbeddedFonts {
|
||||||
|
fn load_face(lib: &Library, name: &str) -> Result<Face, cairo::freetype::Error> {
|
||||||
|
let font_file = FontFiles::get(name).unwrap();
|
||||||
|
let font_data = Vec::from(font_file.data);
|
||||||
|
lib.new_memory_face(font_data, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load() -> EmbeddedFonts {
|
||||||
|
let lib = Library::init().unwrap();
|
||||||
|
let font_regular = Self::load_face(&lib, "Nunito-Regular.ttf").unwrap();
|
||||||
|
let font_light = Self::load_face(&lib, "Nunito-Light.ttf").unwrap();
|
||||||
|
|
||||||
|
let fonts = InternalFonts {
|
||||||
|
regular: font_regular,
|
||||||
|
light: font_light,
|
||||||
|
};
|
||||||
|
|
||||||
|
EmbeddedFonts {
|
||||||
|
fonts: Arc::new(Mutex::new(fonts)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get(&self) -> (Face, Face) {
|
||||||
|
let fonts = self.fonts.lock().await;
|
||||||
|
(fonts.regular.clone(), fonts.light.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DrawableText {
|
||||||
|
pub position: (f64, f64),
|
||||||
|
pub size: f64,
|
||||||
|
pub spacing: f64,
|
||||||
|
pub text: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DrawableText {
|
||||||
|
pub fn draw(&self, context: &Context) {
|
||||||
|
context.new_path();
|
||||||
|
context.set_font_size(self.size);
|
||||||
|
context.line_to(self.position.0, self.position.1);
|
||||||
|
|
||||||
|
for char in self.text.chars() {
|
||||||
|
context.text_path(&String::from(char));
|
||||||
|
let (x, y) = context.current_point().unwrap();
|
||||||
|
context.line_to(x + self.spacing, y);
|
||||||
|
}
|
||||||
|
context.close_path();
|
||||||
|
context.fill().unwrap();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue