Detect & read QR codes from certificate scans

This commit is contained in:
Araozu 2023-11-13 14:29:14 -05:00
parent eba366997a
commit 5939995477
10 changed files with 627 additions and 4 deletions

374
backend/Cargo.lock generated
View File

@ -59,6 +59,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "anyhow"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]] [[package]]
name = "async-channel" name = "async-channel"
version = "1.9.0" version = "1.9.0"
@ -128,13 +134,16 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
name = "backend" name = "backend"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bardecoder",
"chrono", "chrono",
"dotenvy", "dotenvy",
"env_logger", "env_logger",
"image",
"isahc", "isahc",
"lazy_static", "lazy_static",
"log", "log",
"once_cell", "once_cell",
"printpdf",
"reqwest", "reqwest",
"rocket", "rocket",
"scraper", "scraper",
@ -158,6 +167,19 @@ dependencies = [
"rustc-demangle", "rustc-demangle",
] ]
[[package]]
name = "bardecoder"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "757eeab9757d5ddd88aa1420449f3ce92631339b7f5b3785808da7a148de35d9"
dependencies = [
"anyhow",
"image",
"log",
"newtype_derive",
"thiserror",
]
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.21.2" version = "0.21.2"
@ -176,6 +198,12 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72"
[[package]]
name = "bit_field"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@ -200,12 +228,29 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "bstr"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05"
dependencies = [
"memchr",
"regex-automata 0.3.6",
"serde",
]
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.13.0" version = "3.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
[[package]]
name = "bytemuck"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.4.3" version = "1.4.3"
@ -254,6 +299,12 @@ dependencies = [
"windows-targets", "windows-targets",
] ]
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]] [[package]]
name = "concurrent-queue" name = "concurrent-queue"
version = "2.3.0" version = "2.3.0"
@ -348,6 +399,39 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484"
[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"scopeguard",
]
[[package]] [[package]]
name = "crossbeam-queue" name = "crossbeam-queue"
version = "0.3.8" version = "0.3.8"
@ -367,6 +451,12 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]] [[package]]
name = "crypto-common" name = "crypto-common"
version = "0.1.6" version = "0.1.6"
@ -606,6 +696,22 @@ version = "2.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "exr"
version = "1.71.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8"
dependencies = [
"bit_field",
"flume 0.11.0",
"half",
"lebe",
"miniz_oxide",
"rayon-core",
"smallvec",
"zune-inflate",
]
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "1.9.0" version = "1.9.0"
@ -621,6 +727,15 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
[[package]]
name = "fdeflate"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64d6dafc854908ff5da46ff3f8f473c6984119a2876a383a860246dd7841a868"
dependencies = [
"simd-adler32",
]
[[package]] [[package]]
name = "figment" name = "figment"
version = "0.10.10" version = "0.10.10"
@ -635,6 +750,16 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "flate2"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]] [[package]]
name = "flume" name = "flume"
version = "0.10.14" version = "0.10.14"
@ -647,6 +772,15 @@ dependencies = [
"spin 0.9.8", "spin 0.9.8",
] ]
[[package]]
name = "flume"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
dependencies = [
"spin 0.9.8",
]
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@ -841,6 +975,16 @@ dependencies = [
"wasi 0.11.0+wasi-snapshot-preview1", "wasi 0.11.0+wasi-snapshot-preview1",
] ]
[[package]]
name = "gif"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045"
dependencies = [
"color_quant",
"weezl",
]
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.28.0" version = "0.28.0"
@ -872,6 +1016,15 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "half"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0"
dependencies = [
"crunchy",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.12.3" version = "0.12.3"
@ -1090,6 +1243,25 @@ dependencies = [
"unicode-normalization", "unicode-normalization",
] ]
[[package]]
name = "image"
version = "0.24.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711"
dependencies = [
"bytemuck",
"byteorder",
"color_quant",
"exr",
"gif",
"jpeg-decoder",
"num-rational",
"num-traits",
"png",
"qoi",
"tiff",
]
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.9.3" version = "1.9.3"
@ -1186,6 +1358,15 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]]
name = "jpeg-decoder"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e"
dependencies = [
"rayon",
]
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.64" version = "0.3.64"
@ -1204,6 +1385,12 @@ dependencies = [
"spin 0.5.2", "spin 0.5.2",
] ]
[[package]]
name = "lebe"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.147" version = "0.2.147"
@ -1249,6 +1436,12 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.5" version = "0.4.5"
@ -1286,6 +1479,23 @@ dependencies = [
"tracing-subscriber", "tracing-subscriber",
] ]
[[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 0.3.27",
"weezl",
]
[[package]] [[package]]
name = "mac" name = "mac"
version = "0.1.1" version = "0.1.1"
@ -1330,12 +1540,27 @@ 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.5.0" 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 = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "mime" name = "mime"
version = "0.3.17" version = "0.3.17"
@ -1355,6 +1580,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
dependencies = [ dependencies = [
"adler", "adler",
"simd-adler32",
] ]
[[package]] [[package]]
@ -1412,6 +1638,15 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]]
name = "newtype_derive"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac8cd24d9f185bb7223958d8c1ff7a961b74b1953fd05dba7cc568a63b3861ec"
dependencies = [
"rustc_version",
]
[[package]] [[package]]
name = "nom" name = "nom"
version = "7.1.3" version = "7.1.3"
@ -1470,6 +1705,17 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "num-rational"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.16" version = "0.2.16"
@ -1555,6 +1801,15 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "owned_ttf_parser"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60ac8dda2e5cc09bf6480e3b3feff9783db251710c922ae9369a429c51efdeb0"
dependencies = [
"ttf-parser",
]
[[package]] [[package]]
name = "parking" name = "parking"
version = "2.1.1" version = "2.1.1"
@ -1767,6 +2022,19 @@ 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 = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "png"
version = "0.17.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64"
dependencies = [
"bitflags 1.3.2",
"crc32fast",
"fdeflate",
"flate2",
"miniz_oxide",
]
[[package]] [[package]]
name = "polling" name = "polling"
version = "2.8.0" version = "2.8.0"
@ -1783,6 +2051,15 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "pom"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c2d73a5fe10d458e77534589512104e5aa8ac480aa9ac30b74563274235cce4"
dependencies = [
"bstr",
]
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.17" version = "0.2.17"
@ -1795,6 +2072,19 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "printpdf"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f626e180738289baa7ea2d70e603698520735060a664141203cc17bd8e4379c0"
dependencies = [
"image",
"js-sys",
"lopdf",
"owned_ttf_parser",
"time 0.3.27",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.66" version = "1.0.66"
@ -1833,6 +2123,15 @@ dependencies = [
"psl-types", "psl-types",
] ]
[[package]]
name = "qoi"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001"
dependencies = [
"bytemuck",
]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.33" version = "1.0.33"
@ -1872,6 +2171,26 @@ dependencies = [
"getrandom", "getrandom",
] ]
[[package]]
name = "rayon"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.3.5" version = "0.3.5"
@ -2134,6 +2453,15 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustc_version"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
dependencies = [
"semver",
]
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.8" version = "0.38.8"
@ -2279,6 +2607,12 @@ dependencies = [
"smallvec", "smallvec",
] ]
[[package]]
name = "semver"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.188" version = "1.0.188"
@ -2390,6 +2724,12 @@ dependencies = [
"rand_core", "rand_core",
] ]
[[package]]
name = "simd-adler32"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]] [[package]]
name = "siphasher" name = "siphasher"
version = "0.3.11" version = "0.3.11"
@ -2665,7 +3005,7 @@ checksum = "be4c21bf34c7cae5b283efb3ac1bcc7670df7561124dc2f8bdc0b59be40f79a2"
dependencies = [ dependencies = [
"atoi", "atoi",
"chrono", "chrono",
"flume", "flume 0.10.14",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-executor", "futures-executor",
@ -2831,6 +3171,17 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "tiff"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211"
dependencies = [
"flate2",
"jpeg-decoder",
"weezl",
]
[[package]] [[package]]
name = "time" name = "time"
version = "0.1.45" version = "0.1.45"
@ -3068,6 +3419,12 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
[[package]]
name = "ttf-parser"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ae2f58a822f08abdaf668897e96a5656fe72f5a9ce66422423e8849384872e6"
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.16.0" version = "1.16.0"
@ -3306,6 +3663,12 @@ dependencies = [
"rustls-webpki", "rustls-webpki",
] ]
[[package]]
name = "weezl"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
[[package]] [[package]]
name = "whoami" name = "whoami"
version = "1.4.1" version = "1.4.1"
@ -3454,3 +3817,12 @@ name = "zeroize"
version = "1.6.0" version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
[[package]]
name = "zune-inflate"
version = "0.2.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
dependencies = [
"simd-adler32",
]

View File

@ -19,5 +19,8 @@ lazy_static = "1.4.0"
once_cell = "1.18.0" once_cell = "1.18.0"
log = "0.4.20" log = "0.4.20"
env_logger = "0.10.0" env_logger = "0.10.0"
bardecoder = "0.5.0"
image = "0.24.7"
printpdf = { version = "0.6.0", features = ["image", "embedded_images"] }

View File

@ -3,3 +3,4 @@ pub mod course;
pub mod custom_label; pub mod custom_label;
pub mod person; pub mod person;
pub mod register; pub mod register;
pub mod scans;

View File

@ -1,4 +1,4 @@
use log::{info, error}; use log::{error, info};
use reqwest::Client; use reqwest::Client;
use rocket::http::Status; use rocket::http::Status;
use rocket::serde::json::Json; use rocket::serde::json::Json;

View File

@ -0,0 +1,125 @@
use crate::json_result::JsonResult;
use printpdf::{Mm, PdfDocument};
use rocket::{http::Status, serde::json::Json};
use std::{
fs::{self, File},
io::BufWriter,
path::PathBuf,
};
const SCAN_PATH: &str = "/srv/srv/shares/eegsac/ESCANEOS/";
#[get("/scans/detect")]
pub async fn detect_scans() -> (Status, Json<JsonResult<Vec<String>>>) {
// TODO: Move to ENV variable?
let paths = match fs::read_dir(SCAN_PATH) {
Ok(paths) => paths,
Err(err) => {
eprintln!("Error reading dir: {:?}", err);
return (
Status::InternalServerError,
JsonResult::err("Error leyendo directorio".into()),
);
}
};
let mut result = Vec::<String>::new();
for p in paths {
let p = match p {
Ok(p) => p,
Err(err) => {
eprintln!("Error reading path: {:?}", err);
return (
Status::InternalServerError,
JsonResult::err("Error leyendo directorio".into()),
);
}
};
let file_path = p.path();
if file_path.is_dir() {
continue;
}
let filename = match file_path.file_name() {
Some(filename) => filename,
None => {
eprintln!("Error getting file name: {:?}", file_path);
return (
Status::InternalServerError,
JsonResult::err("Error leyendo archivo en directorio".into()),
);
}
};
let filename = match filename.to_str() {
Some(p) => p,
None => {
eprintln!("Error getting file as string: {:?}", p);
return (
Status::InternalServerError,
JsonResult::err("Error leyendo directorio".into()),
);
}
};
if filename.ends_with(".jpg") && filename.starts_with("eeg") {
result.push(filename.to_string());
}
}
for filename in result.iter() {
let path = PathBuf::from(format!("{}{}", SCAN_PATH, filename));
examine_scan(&path);
}
(Status::Ok, JsonResult::ok(result))
}
fn examine_scan(path: &PathBuf) {
let img = image::open(path).unwrap();
// Get width & height
let width = img.width();
let height = img.height();
let third_point_height = (height / 3) * 2;
let mid_point_width = width / 2;
let remaining_height = height - third_point_height;
// crop image
let cropped_img = img.crop_imm(0, third_point_height, mid_point_width, remaining_height);
// get qr from cropped image
let results = bardecoder::default_decoder().decode(&cropped_img);
// TODO: get first qr, parse, query db, get info, determine filename
for result in results {
println!("{}", result.unwrap());
}
// Rotate image 90 degrees clockwise
let img = img.rotate270();
// Generate PDF
let (doc, page1, layer1) =
PdfDocument::new("PDF_Document_title", Mm(297.0), Mm(210.0), "Layer 1");
let current_layer = doc.get_page(page1).get_layer(layer1);
let pdf_image = printpdf::image::Image::from_dynamic_image(&img);
let img_transform = printpdf::ImageTransform::default();
let img_transform = printpdf::ImageTransform {
dpi: Some(200.0),
..img_transform
};
pdf_image.add_to_layer(current_layer, img_transform);
//
doc.save(&mut BufWriter::new(
File::create(format!("{}output.pdf", SCAN_PATH)).unwrap(),
))
.unwrap();
}

View File

@ -68,6 +68,10 @@ async fn rocket() -> _ {
controller::classroom::get_expiration_date, controller::classroom::get_expiration_date,
controller::classroom::set_expiration_date_options, controller::classroom::set_expiration_date_options,
controller::classroom::set_expiration_date, controller::classroom::set_expiration_date,
//
// Scans routes
//
controller::scans::detect_scans,
], ],
) )
} }

View File

@ -9,7 +9,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inconsolata&family=Inter:wght@400;700;900&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inconsolata&family=Inter:wght@400;500;700;900&display=swap" rel="stylesheet">
<style type="text/css"> <style type="text/css">
@font-face { @font-face {

View File

@ -3,6 +3,7 @@ import { type Component } from "solid-js";
import { Certs } from "./certs"; import { Certs } from "./certs";
import { NavRail } from "./components/NavRail"; import { NavRail } from "./components/NavRail";
import { OnlineClassroom } from "./OnlineClassroom"; import { OnlineClassroom } from "./OnlineClassroom";
import { Scans } from "./Scans";
const App: Component = () => ( const App: Component = () => (
<div class="grid grid-cols-[5rem_auto]"> <div class="grid grid-cols-[5rem_auto]">
@ -11,7 +12,7 @@ const App: Component = () => (
<Route path="/" component={() => <Builder />} /> <Route path="/" component={() => <Builder />} />
<Route path="/certs" component={Certs} /> <Route path="/certs" component={Certs} />
<Route path="/accesos" component={OnlineClassroom} /> <Route path="/accesos" component={OnlineClassroom} />
<Route path="/escaneo" component={() => <p>En construccion</p>} /> <Route path="/escaneo" component={Scans} />
</Routes> </Routes>
</div> </div>
); );

View File

@ -0,0 +1,115 @@
import { FilledButton } from "../components/FilledButton";
import { FilledCard } from "../components/FilledCard";
export function Scans() {
const detectScans = () => {
fetch(`${import.meta.env.VITE_BACKEND_URL}/api/scans/detect`)
.then((res) => res.json())
.then(console.log);
};
return (
<div class="grid grid-cols-[25rem_25rem_auto]">
<div>
<FilledCard>
<h1 class="py-2 px-4 font-medium text-xl mb-2">
Ruta de la carpeta "Certificados"
</h1>
<div class="px-2">
<input
class="w-full p-2 border border-c-outline rounded-md font-mono"
type="text"
value="/srv/srv/shares/eegsac/ESCANEOS/"
/>
<p class="py-2 px-2">
Si no hay ningún problema con la ruta, no es necesario cambiarla.
<br />
Esta ruta es relativa al servidor, no al cliente.
</p>
</div>
</FilledCard>
<FilledCard>
<h1 class="py-2 px-4 font-medium text-xl mb-2">
Parámetros de detección
</h1>
<div class="px-4 pb-4">
Para que el sistema detecte y clasifique automáticamente los escaneos
se debe cumplir lo siguiente:
<ol class="py-2 px-2 list-decimal list-inside">
<li>
Escanear el certificado en formato&nbsp;
<code class="border border-c-outline rounded p-1 bg-c-background">
jpg
</code>
</li>
<li>
El nombre del archivo debe iniciar con&nbsp;
<code class="border border-c-outline rounded p-1 bg-c-background">
eeg
</code>
</li>
<li>
El nombre del archivo debe terminar en&nbsp;
<code class="border border-c-outline rounded p-1 bg-c-background">
.jpg
</code>
</li>
<li>
El nombre del archivo puede tener otras letras en medio,
siempre que se cumplan las condiciones anteriores.
</li>
</ol>
Por ejemplo, los siguientes nombres de archivo son válidos:
<ul class="py-2 px-2 list-disc list-inside">
<li>
<code class="border border-c-outline rounded p-1 bg-c-background">
eeg.jpg
</code>
</li>
<li>
<code class="border border-c-outline rounded p-1 bg-c-background">
eeg0001.jpg
</code>
</li>
<li>
<code class="border border-c-outline rounded p-1 bg-c-background">
eeg archivo con letras en medio.jpg
</code>
</li>
</ul>
</div>
</FilledCard>
</div>
<div>
<FilledCard>
<h1 class="py-2 px-4 font-medium text-xl mb-2">
Detectar escaneos
</h1>
<div class="px-4 pb-4">
El siguiente botón detectará los escaneos en la carpeta
que cumplen con los parámetros de detección, y los mostrará
en una lista.
<br />
<FilledButton
class="mt-2"
onClick={detectScans}
>
Detectar escaneos
</FilledButton>
</div>
</FilledCard>
<FilledCard class="border border-c-outline overflow-hidden">
<h1 class="p-3 font-medium text-xl">
Escaneos detectados
</h1>
<div class="bg-c-surface p-4">
:D
</div>
</FilledCard>
</div>
</div>
);
}

View File

@ -4,6 +4,7 @@ export function FilledButton(props: {
children?: Array<JSX.Element> | JSX.Element, children?: Array<JSX.Element> | JSX.Element,
class?: string, class?: string,
type?: "button" | "submit", type?: "button" | "submit",
onClick?: () => void,
disabled?: boolean, disabled?: boolean,
}) { }) {
return ( return (
@ -11,6 +12,7 @@ export function FilledButton(props: {
class={`bg-c-primary text-c-on-primary px-4 py-2 rounded-full cursor-pointer mt-4 class={`bg-c-primary text-c-on-primary px-4 py-2 rounded-full cursor-pointer mt-4
disabled:opacity-50 disabled:cursor-not-allowed ${props.class}`} disabled:opacity-50 disabled:cursor-not-allowed ${props.class}`}
disabled={props.disabled} disabled={props.disabled}
onClick={props.onClick}
> >
{props.children} {props.children}
</button> </button>