Add label printing
This commit is contained in:
parent
21c99a1677
commit
af2ce1e9b1
432
Cargo.lock
generated
432
Cargo.lock
generated
|
@ -88,7 +88,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
|
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -204,7 +204,7 @@ dependencies = [
|
||||||
"actix-router",
|
"actix-router",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -244,6 +244,12 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aliasable"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "alloc-no-stdlib"
|
name = "alloc-no-stdlib"
|
||||||
version = "2.0.4"
|
version = "2.0.4"
|
||||||
|
@ -259,6 +265,33 @@ dependencies = [
|
||||||
"alloc-no-stdlib",
|
"alloc-no-stdlib",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "allsorts"
|
||||||
|
version = "0.14.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "afb67debdbc7e8b0716e7b10ce247ff6cd2811b0b478969158b16ac58995d16b"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"bitreader",
|
||||||
|
"brotli-decompressor 2.5.1",
|
||||||
|
"byteorder",
|
||||||
|
"encoding_rs",
|
||||||
|
"flate2",
|
||||||
|
"glyph-names",
|
||||||
|
"itertools",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"num-traits",
|
||||||
|
"ouroboros",
|
||||||
|
"rustc-hash",
|
||||||
|
"tinyvec",
|
||||||
|
"ucd-trie",
|
||||||
|
"unicode-canonical-combining-class",
|
||||||
|
"unicode-general-category",
|
||||||
|
"unicode-joining-type",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstream"
|
name = "anstream"
|
||||||
version = "0.6.14"
|
version = "0.6.14"
|
||||||
|
@ -308,6 +341,12 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrayvec"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "askama"
|
name = "askama"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
|
@ -344,7 +383,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde",
|
"serde",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -370,7 +409,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -394,6 +433,12 @@ dependencies = [
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "barcoders"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3826fb6e98ec72c0c0db8c9a40af4932d16793021027469857e84c1b50a1e8f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.21.7"
|
version = "0.21.7"
|
||||||
|
@ -427,6 +472,15 @@ version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitreader"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bdd859c9d97f7c468252795b35aeccc412bdbb1e90ee6969c4fa6328272eaeff"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
|
@ -444,7 +498,17 @@ checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloc-no-stdlib",
|
"alloc-no-stdlib",
|
||||||
"alloc-stdlib",
|
"alloc-stdlib",
|
||||||
"brotli-decompressor",
|
"brotli-decompressor 4.0.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "brotli-decompressor"
|
||||||
|
version = "2.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f"
|
||||||
|
dependencies = [
|
||||||
|
"alloc-no-stdlib",
|
||||||
|
"alloc-stdlib",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -457,6 +521,17 @@ dependencies = [
|
||||||
"alloc-stdlib",
|
"alloc-stdlib",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bstr"
|
||||||
|
version = "1.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.16.0"
|
version = "3.16.0"
|
||||||
|
@ -542,6 +617,31 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-common"
|
name = "crypto-common"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
|
@ -573,7 +673,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"strsim",
|
"strsim",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -584,7 +684,17 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "datamatrix"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9133f6cb9217da268046cfa9b5916b37d7c77c11707a8b7e95474a816154c42"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"flagset",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -623,7 +733,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -662,7 +772,7 @@ dependencies = [
|
||||||
"heck 0.4.1",
|
"heck 0.4.1",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -675,7 +785,7 @@ dependencies = [
|
||||||
"dsl_auto_type",
|
"dsl_auto_type",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -695,7 +805,7 @@ version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25"
|
checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -720,7 +830,7 @@ dependencies = [
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -773,6 +883,12 @@ version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flagset"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdeb3aa5e95cf9aabc17f060cfa0ced7b83f042390760ca53bf09df9968acaa1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.30"
|
version = "1.0.30"
|
||||||
|
@ -822,7 +938,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -879,6 +995,12 @@ version = "0.29.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
|
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glyph-names"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3531d702d6c1a3ba92a5fb55a404c7b8c476c8e7ca249951077afcbe4bc807f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.3.26"
|
version = "0.3.26"
|
||||||
|
@ -1007,6 +1129,15 @@ version = "1.70.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
|
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.10.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.11"
|
version = "1.0.11"
|
||||||
|
@ -1037,6 +1168,12 @@ version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
|
checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "li7y"
|
name = "li7y"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
@ -1045,13 +1182,19 @@ dependencies = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"askama",
|
"askama",
|
||||||
"askama_actix",
|
"askama_actix",
|
||||||
|
"barcoders",
|
||||||
|
"datamatrix",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
"diesel-derive-enum",
|
"diesel-derive-enum",
|
||||||
"diesel_migrations",
|
"diesel_migrations",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
|
"mime",
|
||||||
|
"printpdf",
|
||||||
|
"rust-fontconfig",
|
||||||
"serde",
|
"serde",
|
||||||
|
"thiserror",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1067,6 +1210,12 @@ version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linked-hash-map"
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "local-channel"
|
name = "local-channel"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
@ -1100,6 +1249,23 @@ version = "0.4.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lopdf"
|
||||||
|
version = "0.31.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07c8e1b6184b1b32ea5f72f572ebdc40e5da1d2921fa469947ff7c480ad1f85a"
|
||||||
|
dependencies = [
|
||||||
|
"encoding_rs",
|
||||||
|
"flate2",
|
||||||
|
"itoa",
|
||||||
|
"linked-hash-map",
|
||||||
|
"log",
|
||||||
|
"md5",
|
||||||
|
"pom",
|
||||||
|
"time",
|
||||||
|
"weezl",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "md-5"
|
name = "md-5"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
|
@ -1110,6 +1276,12 @@ dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "md5"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.4"
|
version = "2.7.4"
|
||||||
|
@ -1180,6 +1352,16 @@ dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mmapio"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0204e2cac68f5b2e35b7ec8cb5d906f6e58e78dad8066a30b6ee54da99bb03dd"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "7.1.3"
|
version = "7.1.3"
|
||||||
|
@ -1230,6 +1412,39 @@ version = "1.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ouroboros"
|
||||||
|
version = "0.17.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2ba07320d39dfea882faa70554b4bd342a5f273ed59ba7c1c6b4c840492c954"
|
||||||
|
dependencies = [
|
||||||
|
"aliasable",
|
||||||
|
"ouroboros_macro",
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ouroboros_macro"
|
||||||
|
version = "0.17.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8"
|
||||||
|
dependencies = [
|
||||||
|
"heck 0.4.1",
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.68",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "owned_ttf_parser"
|
||||||
|
version = "0.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "706de7e2214113d63a8238d1910463cfce781129a6f263d13fdb09ff64355ba4"
|
||||||
|
dependencies = [
|
||||||
|
"ttf-parser",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
|
@ -1301,6 +1516,15 @@ version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pom"
|
||||||
|
version = "3.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c972d8f86e943ad532d0b04e8965a749ad1d18bb981a9c7b3ae72fe7fd7744b"
|
||||||
|
dependencies = [
|
||||||
|
"bstr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "postgres-protocol"
|
name = "postgres-protocol"
|
||||||
version = "0.6.6"
|
version = "0.6.6"
|
||||||
|
@ -1342,6 +1566,42 @@ version = "0.2.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "printpdf"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c30a4cc87c3ca9a98f4970db158a7153f8d1ec8076e005751173c57836380b1d"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"lopdf",
|
||||||
|
"owned_ttf_parser",
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error-attr",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error-attr"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.86"
|
version = "1.0.86"
|
||||||
|
@ -1390,6 +1650,26 @@ dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
|
@ -1443,12 +1723,30 @@ version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-fontconfig"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ea6002602a06c22f5f4e5ea2ed68854bfce071b48e1092c03874e34d0b59eb4b"
|
||||||
|
dependencies = [
|
||||||
|
"allsorts",
|
||||||
|
"mmapio",
|
||||||
|
"rayon",
|
||||||
|
"xmlparser",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.24"
|
version = "0.1.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -1503,7 +1801,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1600,6 +1898,12 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stringprep"
|
name = "stringprep"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
@ -1623,6 +1927,16 @@ version = "2.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.109"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.68"
|
version = "2.0.68"
|
||||||
|
@ -1634,6 +1948,26 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.61"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.61"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.68",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.36"
|
version = "0.3.36"
|
||||||
|
@ -1790,12 +2124,24 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ttf-parser"
|
||||||
|
version = "0.19.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49d64318d8311fc2668e48b63969f4343e0a85c4a109aa8460d6672e364b8bd1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.17.0"
|
version = "1.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ucd-trie"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicase"
|
name = "unicase"
|
||||||
version = "2.7.0"
|
version = "2.7.0"
|
||||||
|
@ -1811,12 +2157,30 @@ version = "0.3.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-canonical-combining-class"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6925586af9268182c711e47c0853ed84131049efaca41776d0ca97f983865c32"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-general-category"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2281c8c1d221438e373249e065ca4989c4c36952c211ff21a0ee91c44a3869e7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-joining-type"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22f8cb47ccb8bc750808755af3071da4a10dcd147b68fc874b7ae4b12543f6f5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
version = "0.1.23"
|
version = "0.1.23"
|
||||||
|
@ -1904,7 +2268,7 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1926,7 +2290,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
@ -1947,6 +2311,12 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "weezl"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "whoami"
|
name = "whoami"
|
||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
|
@ -1958,6 +2328,28 @@ dependencies = [
|
||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
|
@ -2106,6 +2498,12 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xmlparser"
|
||||||
|
version = "0.13.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.34"
|
version = "0.7.34"
|
||||||
|
@ -2123,7 +2521,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -14,11 +14,17 @@ actix-files = "0.6.6"
|
||||||
actix-web = "4.8.0"
|
actix-web = "4.8.0"
|
||||||
askama = { version = "0.12.1", features = ["with-actix-web"] }
|
askama = { version = "0.12.1", features = ["with-actix-web"] }
|
||||||
askama_actix = "0.14.0"
|
askama_actix = "0.14.0"
|
||||||
|
barcoders = { version = "2.0.0", default-features = false, features = ["std"] }
|
||||||
|
datamatrix = "0.3.1"
|
||||||
diesel = { version = "2.2.1", features = ["uuid"] }
|
diesel = { version = "2.2.1", features = ["uuid"] }
|
||||||
diesel-async = { git = "https://github.com/weiznich/diesel_async.git", version = "0.4.1", features = ["postgres", "deadpool", "async-connection-wrapper"] }
|
diesel-async = { git = "https://github.com/weiznich/diesel_async.git", version = "0.4.1", features = ["postgres", "deadpool", "async-connection-wrapper"] }
|
||||||
diesel-derive-enum = { version = "2.1.0", features = ["postgres"] }
|
diesel-derive-enum = { version = "2.1.0", features = ["postgres"] }
|
||||||
diesel_migrations = { version = "2.2.0", features = ["postgres"] }
|
diesel_migrations = { version = "2.2.0", features = ["postgres"] }
|
||||||
env_logger = "0.11.3"
|
env_logger = "0.11.3"
|
||||||
log = "0.4.21"
|
log = "0.4.21"
|
||||||
|
mime = "0.3.17"
|
||||||
|
printpdf = "0.7.0"
|
||||||
|
rust-fontconfig = "0.1.7"
|
||||||
serde = { version = "1.0.203", features = ["serde_derive"] }
|
serde = { version = "1.0.203", features = ["serde_derive"] }
|
||||||
|
thiserror = "1.0.61"
|
||||||
uuid = { version = "1.9.0", features = ["serde", "v4"] }
|
uuid = { version = "1.9.0", features = ["serde", "v4"] }
|
||||||
|
|
55
src/api/v1/label.rs
Normal file
55
src/api/v1/label.rs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
use actix_web::http::header::{ContentDisposition, ContentType, DispositionParam, DispositionType};
|
||||||
|
use actix_web::{error, get, web, HttpResponse, Responder};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use crate::label::{Label, LabelPage, LabelPreset};
|
||||||
|
|
||||||
|
pub fn config(cfg: &mut web::ServiceConfig) {
|
||||||
|
cfg.service(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct QueryParams {
|
||||||
|
// FIXME: serde_urlencoded does not support sequences
|
||||||
|
ids: String,
|
||||||
|
preset: LabelPreset,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/label/items")]
|
||||||
|
async fn items(params: web::Query<QueryParams>) -> actix_web::Result<impl Responder> {
|
||||||
|
let ids = params
|
||||||
|
.ids
|
||||||
|
.split(',')
|
||||||
|
.skip_while(|s| s.is_empty()) // to make the empty string parse as an empty iterator
|
||||||
|
.map(Uuid::try_parse)
|
||||||
|
.collect::<Result<Vec<Uuid>, uuid::Error>>()
|
||||||
|
.map_err(error::ErrorInternalServerError)?;
|
||||||
|
|
||||||
|
let label_config = params.preset.clone().into();
|
||||||
|
|
||||||
|
let label = Label {
|
||||||
|
pages: ids
|
||||||
|
.into_iter()
|
||||||
|
.map(|id| LabelPage {
|
||||||
|
id: Some(id),
|
||||||
|
short_id: None,
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
config: label_config,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok()
|
||||||
|
.insert_header(ContentType(mime::APPLICATION_PDF))
|
||||||
|
.insert_header(ContentDisposition {
|
||||||
|
disposition: DispositionType::Inline,
|
||||||
|
parameters: vec![DispositionParam::Filename(
|
||||||
|
"li7y-item-labels.pdf".to_string(),
|
||||||
|
)],
|
||||||
|
})
|
||||||
|
.body(label.generate().map_err(error::ErrorInternalServerError)?))
|
||||||
|
}
|
|
@ -4,9 +4,12 @@
|
||||||
|
|
||||||
mod item;
|
mod item;
|
||||||
mod item_class;
|
mod item_class;
|
||||||
|
mod label;
|
||||||
|
|
||||||
use actix_web::web;
|
use actix_web::web;
|
||||||
|
|
||||||
pub fn config(cfg: &mut web::ServiceConfig) {
|
pub fn config(cfg: &mut web::ServiceConfig) {
|
||||||
cfg.configure(item::config).configure(item_class::config);
|
cfg.configure(item::config)
|
||||||
|
.configure(item_class::config)
|
||||||
|
.configure(label::config);
|
||||||
}
|
}
|
||||||
|
|
60
src/label/barcode.rs
Normal file
60
src/label/barcode.rs
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
use barcoders::sym::code128::Code128;
|
||||||
|
use datamatrix::{DataMatrix, SymbolSize};
|
||||||
|
use printpdf::{ColorBits, ColorSpace, Image, ImageXObject, Px};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
fn create_image(width: usize, height: usize, data: Vec<bool>) -> Image {
|
||||||
|
Image::from(ImageXObject {
|
||||||
|
width: Px(width),
|
||||||
|
height: Px(height),
|
||||||
|
color_space: ColorSpace::Greyscale,
|
||||||
|
bits_per_component: ColorBits::Bit8, // TODO: why does Bit1 not work?
|
||||||
|
image_data: data
|
||||||
|
.iter()
|
||||||
|
.map(|x| match x {
|
||||||
|
true => 0,
|
||||||
|
false => u8::MAX,
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
interpolate: false,
|
||||||
|
image_filter: None,
|
||||||
|
smask: None,
|
||||||
|
clipping_bbox: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encode_data_matrix(id: Uuid) -> Result<Image, datamatrix::data::DataEncodingError> {
|
||||||
|
let code = DataMatrix::encode(
|
||||||
|
&id.to_string().bytes().collect::<Vec<u8>>(),
|
||||||
|
SymbolSize::Square22,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let bitmap = code.bitmap();
|
||||||
|
assert_eq!(bitmap.width(), 22);
|
||||||
|
assert_eq!(bitmap.height(), 22);
|
||||||
|
|
||||||
|
let mut buf = vec![false; bitmap.width() * bitmap.height()];
|
||||||
|
for (x, y) in bitmap.pixels() {
|
||||||
|
buf[x + y * bitmap.width()] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(create_image(22, 22, buf))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encode_code128(text: String) -> Result<Image, barcoders::error::Error> {
|
||||||
|
let mut text = text;
|
||||||
|
// barcoders uses special characters for setting the Code128 type (A, B, C)
|
||||||
|
text.insert(0, 'À');
|
||||||
|
|
||||||
|
let buf: Vec<bool> = Code128::new(text)?
|
||||||
|
.encode()
|
||||||
|
.iter()
|
||||||
|
.map(|x| !matches!(x, 0))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(create_image(buf.len(), 1, buf))
|
||||||
|
}
|
239
src/label/mod.rs
Normal file
239
src/label/mod.rs
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
mod barcode;
|
||||||
|
mod preset;
|
||||||
|
|
||||||
|
use std::fs::File;
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
|
use pdf::{IndirectFontRef, PdfLayerReference};
|
||||||
|
use printpdf as pdf;
|
||||||
|
use printpdf::{ImageTransform, Mm, PdfDocument, PdfDocumentReference, Pt, Px};
|
||||||
|
use rust_fontconfig::{FcFontCache, FcPattern};
|
||||||
|
use thiserror::Error;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use barcode::{encode_code128, encode_data_matrix};
|
||||||
|
pub use preset::LabelPreset;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("could not encode data matrix")]
|
||||||
|
DataMatrixEncoding(datamatrix::data::DataEncodingError),
|
||||||
|
#[error("could not encode barcode: {0}]")]
|
||||||
|
Barcoders(#[from] barcoders::error::Error),
|
||||||
|
#[error("IO error: {0}")]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
#[error("PDF error: {0}")]
|
||||||
|
PrintPdf(#[from] printpdf::Error),
|
||||||
|
|
||||||
|
#[error("data is incomplete ({0} not given in data, but required in config)")]
|
||||||
|
DataIncomplete(String),
|
||||||
|
#[error("can’t create labels without any pages")]
|
||||||
|
NoPages,
|
||||||
|
}
|
||||||
|
|
||||||
|
// The datamatrix crate does not implement Into<std::error::Error> for its error type
|
||||||
|
impl From<datamatrix::data::DataEncodingError> for Error {
|
||||||
|
fn from(value: datamatrix::data::DataEncodingError) -> Self {
|
||||||
|
Self::DataMatrixEncoding(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
// this is implemented based on lazy_static’s recommendation
|
||||||
|
fn fc_cache() -> &'static FcFontCache {
|
||||||
|
static FC_CACHE: OnceLock<FcFontCache> = OnceLock::new();
|
||||||
|
FC_CACHE.get_or_init(FcFontCache::build)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_font_path(name: &str) -> String {
|
||||||
|
fc_cache()
|
||||||
|
.query(&FcPattern {
|
||||||
|
name: Some(name.to_string()),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.expect("Could not find font")
|
||||||
|
.path
|
||||||
|
.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mm_to_scale_factor(mm: Mm, size: Px) -> f32 {
|
||||||
|
mm / Mm::from(Pt(0.24 * (size.0 as f32)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct LabelConfig {
|
||||||
|
width: Mm,
|
||||||
|
height: Mm,
|
||||||
|
data_matrix: Option<DataMatrixConfig>,
|
||||||
|
code128: Option<Code128Config>,
|
||||||
|
id_text: Option<IdTextConfig>,
|
||||||
|
short_id_text: Option<IdTextConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DataMatrixConfig {
|
||||||
|
scale: Mm,
|
||||||
|
position: (Mm, Mm),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DataMatrixConfig {
|
||||||
|
fn draw(&self, layer: &PdfLayerReference, id: Option<Uuid>) -> Result<()> {
|
||||||
|
let image = encode_data_matrix(id.ok_or(Error::DataIncomplete("UUID".to_string()))?)?;
|
||||||
|
|
||||||
|
let size = image.image.width;
|
||||||
|
|
||||||
|
image.add_to_layer(
|
||||||
|
layer.clone(),
|
||||||
|
ImageTransform {
|
||||||
|
translate_x: Some(self.position.0),
|
||||||
|
translate_y: Some(self.position.1),
|
||||||
|
scale_x: Some(mm_to_scale_factor(self.scale, size)),
|
||||||
|
scale_y: Some(mm_to_scale_factor(self.scale, size)),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Code128Config {
|
||||||
|
scale: (Mm, Mm),
|
||||||
|
position: (Mm, Mm),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Code128Config {
|
||||||
|
fn draw<S: Into<String>>(&self, layer: &PdfLayerReference, id: Option<S>) -> Result<()> {
|
||||||
|
let image = encode_code128(
|
||||||
|
id.ok_or(Error::DataIncomplete("short ID".to_string()))?
|
||||||
|
.into(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let width = image.image.width;
|
||||||
|
|
||||||
|
image.add_to_layer(
|
||||||
|
layer.clone(),
|
||||||
|
ImageTransform {
|
||||||
|
translate_x: Some(self.position.0),
|
||||||
|
translate_y: Some(self.position.1),
|
||||||
|
scale_x: Some(mm_to_scale_factor(self.scale.0, width)),
|
||||||
|
scale_y: Some(mm_to_scale_factor(self.scale.1, Px(1))),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct IdTextConfig {
|
||||||
|
font_size: f32,
|
||||||
|
position: (Mm, Mm),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IdTextConfig {
|
||||||
|
fn draw<S: Into<String>>(
|
||||||
|
&self,
|
||||||
|
layer: &PdfLayerReference,
|
||||||
|
font: &IndirectFontRef,
|
||||||
|
text: Option<S>,
|
||||||
|
) -> Result<()> {
|
||||||
|
layer.use_text(
|
||||||
|
text.ok_or(Error::DataIncomplete("ID text".to_string()))?,
|
||||||
|
self.font_size,
|
||||||
|
self.position.0,
|
||||||
|
self.position.1,
|
||||||
|
font,
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct LabelPage {
|
||||||
|
pub id: Option<Uuid>,
|
||||||
|
pub short_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LabelPage {
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
config: &LabelConfig,
|
||||||
|
layer: &PdfLayerReference,
|
||||||
|
font: &IndirectFontRef,
|
||||||
|
) -> Result<()> {
|
||||||
|
if let Some(cfg) = &config.data_matrix {
|
||||||
|
cfg.draw(layer, self.id)?;
|
||||||
|
}
|
||||||
|
if let Some(cfg) = &config.code128 {
|
||||||
|
cfg.draw(layer, self.short_id.as_ref())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(cfg) = &config.id_text {
|
||||||
|
cfg.draw(layer, font, self.id)?;
|
||||||
|
}
|
||||||
|
if let Some(cfg) = &config.short_id_text {
|
||||||
|
cfg.draw(layer, font, self.short_id.as_ref())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Label {
|
||||||
|
pub pages: Vec<LabelPage>,
|
||||||
|
pub config: LabelConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Label {
|
||||||
|
pub fn generate(&self) -> Result<Vec<u8>> {
|
||||||
|
let mut doc: Option<PdfDocumentReference> = None;
|
||||||
|
let mut font: Option<IndirectFontRef> = None;
|
||||||
|
|
||||||
|
for label in &self.pages {
|
||||||
|
let page;
|
||||||
|
let layer;
|
||||||
|
|
||||||
|
let name: String = label
|
||||||
|
.id
|
||||||
|
.map(String::from)
|
||||||
|
.or(label.short_id.clone())
|
||||||
|
.unwrap_or("empty".into());
|
||||||
|
|
||||||
|
if let Some(ref doc) = &doc {
|
||||||
|
(page, layer) = doc.add_page(self.config.width, self.config.height, name);
|
||||||
|
} else {
|
||||||
|
let (new_doc, page1, layer1) =
|
||||||
|
PdfDocument::new("li7y labels", self.config.width, self.config.height, name);
|
||||||
|
// TODO: do not hardcode font
|
||||||
|
// counter-argument: the presets rely on its spacing
|
||||||
|
// but at least it should be somehow included (or at least documented)
|
||||||
|
font =
|
||||||
|
Some(new_doc.add_external_font(File::open(get_font_path(
|
||||||
|
"IosevkaSbruder Nerd Font",
|
||||||
|
))?)?);
|
||||||
|
|
||||||
|
doc = Some(new_doc);
|
||||||
|
page = page1;
|
||||||
|
layer = layer1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let doc = doc.as_ref().unwrap();
|
||||||
|
let font = font.as_ref().unwrap();
|
||||||
|
|
||||||
|
let layer_ref = doc.get_page(page).get_layer(layer);
|
||||||
|
|
||||||
|
label.draw(&self.config, &layer_ref, font)?
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(doc.ok_or(Error::NoPages)?.save_to_bytes()?)
|
||||||
|
}
|
||||||
|
}
|
75
src/label/preset.rs
Normal file
75
src/label/preset.rs
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
use printpdf::Mm;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use super::{Code128Config, DataMatrixConfig, IdTextConfig, LabelConfig};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "kebab-case")]
|
||||||
|
pub enum LabelPreset {
|
||||||
|
SeikoSlpMrlDataMatrix,
|
||||||
|
SeikoSlpMrlCode128,
|
||||||
|
SeikoSlpMrl,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::from_over_into)]
|
||||||
|
impl Into<LabelConfig> for LabelPreset {
|
||||||
|
fn into(self) -> LabelConfig {
|
||||||
|
match self {
|
||||||
|
Self::SeikoSlpMrlDataMatrix => LabelConfig {
|
||||||
|
width: Mm(44.45),
|
||||||
|
height: Mm(24.13),
|
||||||
|
data_matrix: Some(DataMatrixConfig {
|
||||||
|
scale: Mm(20.0),
|
||||||
|
position: (Mm(0.0), Mm(0.0)),
|
||||||
|
}),
|
||||||
|
code128: None,
|
||||||
|
id_text: Some(IdTextConfig {
|
||||||
|
font_size: 7.0,
|
||||||
|
position: (Mm(0.0), Mm(22.0)),
|
||||||
|
}),
|
||||||
|
short_id_text: None,
|
||||||
|
},
|
||||||
|
Self::SeikoSlpMrlCode128 => LabelConfig {
|
||||||
|
width: Mm(44.45),
|
||||||
|
height: Mm(24.13),
|
||||||
|
data_matrix: None,
|
||||||
|
code128: Some(Code128Config {
|
||||||
|
scale: (Mm(44.45), Mm(19.0)),
|
||||||
|
position: (Mm(0.0), Mm(2.5)),
|
||||||
|
}),
|
||||||
|
id_text: Some(IdTextConfig {
|
||||||
|
font_size: 7.0,
|
||||||
|
position: (Mm(0.0), Mm(22.0)),
|
||||||
|
}),
|
||||||
|
short_id_text: Some(IdTextConfig {
|
||||||
|
font_size: 7.0,
|
||||||
|
position: (Mm(0.0), Mm(0.0)),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
Self::SeikoSlpMrl => LabelConfig {
|
||||||
|
width: Mm(44.45),
|
||||||
|
height: Mm(24.13),
|
||||||
|
data_matrix: Some(DataMatrixConfig {
|
||||||
|
scale: Mm(16.0),
|
||||||
|
position: (Mm(0.0), Mm(4.0)),
|
||||||
|
}),
|
||||||
|
code128: Some(Code128Config {
|
||||||
|
scale: (Mm(27.45), Mm(16.0)),
|
||||||
|
position: (Mm(17.0), Mm(4.0)),
|
||||||
|
}),
|
||||||
|
id_text: Some(IdTextConfig {
|
||||||
|
font_size: 7.0,
|
||||||
|
position: (Mm(0.0), Mm(22.0)),
|
||||||
|
}),
|
||||||
|
short_id_text: Some(IdTextConfig {
|
||||||
|
font_size: 7.0,
|
||||||
|
position: (Mm(17.0), Mm(0.0)),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
pub mod api;
|
pub mod api;
|
||||||
pub mod frontend;
|
pub mod frontend;
|
||||||
|
pub mod label;
|
||||||
pub mod manage;
|
pub mod manage;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
|
|
Loading…
Reference in a new issue