commit ca1cdc8179692b2a64f56f410f26b6b8e645ebfc Author: Michael Zhang Date: Tue Aug 3 03:47:17 2021 -0500 Initial Nix build doesn't work, blocked on https://github.com/kolloch/crate2nix/issues/207 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..1a7f0ea --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2495 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "ascii-canvas" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff8eb72df928aafb99fe5d37b383f2fe25bd2a765e3e5f7c365916b6f2463a29" +dependencies = [ + "term", +] + +[[package]] +name = "async-compression" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443ccbb270374a2b1055fc72da40e1f237809cd6bb0e97e66d264cd138473a6" +dependencies = [ + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-stream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625" +dependencies = [ + "async-stream-impl", + "futures-core", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3410529e8288c463bedb5930f82833bc0c90e5d2fe639a56582a4d09220b281" +dependencies = [ + "autocfg 1.0.1", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "base-x" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "binascii" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" + +[[package]] +name = "bit-set" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "bumpalo" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" + +[[package]] +name = "cc" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time 0.1.43", + "winapi", +] + +[[package]] +name = "clap" +version = "3.0.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", + "strsim", + "termcolor", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clap_derive" +version = "3.0.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "const_fn" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "cookie" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f1c7727e460397e56abc4bddc1d49e07a1ad78fc98eb2e1c8f032a58a2f80d" +dependencies = [ + "percent-encoding", + "time 0.2.27", + "version_check", +] + +[[package]] +name = "crc32fast" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if", + "lazy_static", +] + +[[package]] +name = "devise" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c7580b072f1c8476148f16e0a0d5dedddab787da98d86c5082c5e9ed8ab595" +dependencies = [ + "devise_codegen", + "devise_core", +] + +[[package]] +name = "devise_codegen" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123c73e7a6e51b05c75fe1a1b2f4e241399ea5740ed810b0e3e6cacd9db5e7b2" +dependencies = [ + "devise_core", + "quote", +] + +[[package]] +name = "devise_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841ef46f4787d9097405cac4e70fb8644fc037b526e8c14054247c0263c400d0" +dependencies = [ + "bitflags", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", +] + +[[package]] +name = "diff" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "dirs" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "discard" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" + +[[package]] +name = "docopt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f3f119846c823f9eafcf953a8f6ffb6ed69bf6240883261a7f13b634579a51f" +dependencies = [ + "lazy_static", + "regex", + "serde", + "strsim", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "ena" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8944dc8fa28ce4a38f778bd46bf7d923fe73eed5a439398507246c8e017e6f36" +dependencies = [ + "log", +] + +[[package]] +name = "encoding_rs" +version = "0.8.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "figment" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790b4292c72618abbab50f787a477014fe15634f96291de45672ce46afe122df" +dependencies = [ + "atomic", + "pear", + "serde", + "toml", + "uncased", + "version_check", +] + +[[package]] +name = "fixedbitset" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" + +[[package]] +name = "flate2" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" +dependencies = [ + "cfg-if", + "crc32fast", + "libc", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "futures" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" + +[[package]] +name = "futures-executor" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" + +[[package]] +name = "futures-macro" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +dependencies = [ + "autocfg 1.0.1", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" + +[[package]] +name = "futures-task" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" + +[[package]] +name = "futures-util" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +dependencies = [ + "autocfg 1.0.1", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "generator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1d9279ca822891c1a4dae06d185612cf8fc6acfe5dff37781b41297811b12ee" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "winapi", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "h2" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825343c4eef0b63f541f8903f395dc5beb362a979b5799a84062527ef1e37726" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "htmlescape" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" + +[[package]] +name = "http" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68" + +[[package]] +name = "httpdate" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" + +[[package]] +name = "hyper" +version = "0.14.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" +dependencies = [ + "futures-util", + "hyper", + "log", + "rustls", + "tokio", + "tokio-rustls", + "webpki", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +dependencies = [ + "autocfg 1.0.1", + "hashbrown", + "serde", +] + +[[package]] +name = "inlinable_string" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3094308123a0e9fd59659ce45e22de9f53fc1d2ac6e1feb9fef988e4f76cad77" + +[[package]] +name = "instant" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" + +[[package]] +name = "itertools" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "js-sys" +version = "0.3.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce791b7ca6638aae45be056e068fc756d871eb3b3b10b8efa62d1c9cec616752" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lalrpop" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64dc3698e75d452867d9bd86f4a723f452ce9d01fe1d55990b79f0c790aa67db" +dependencies = [ + "ascii-canvas", + "atty", + "bit-set", + "diff", + "docopt", + "ena", + "itertools", + "lalrpop-util", + "petgraph", + "regex", + "regex-syntax", + "serde", + "serde_derive", + "sha2", + "string_cache", + "term", + "unicode-xid 0.1.0", +] + +[[package]] +name = "lalrpop-util" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c277d18683b36349ab5cd030158b54856fca6bb2d5dc5263b06288f486958b7c" + +[[package]] +name = "language-tags" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" + +[[package]] +name = "lock_api" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "loom" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2111607c723d7857e0d8299d5ce7a0bf4b844d3e44f8de136b13da513eaf8fc4" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", +] + +[[package]] +name = "matches" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" + +[[package]] +name = "memchr" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg 1.0.1", +] + +[[package]] +name = "mio" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", +] + +[[package]] +name = "multer" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "408327e2999b839cd1af003fc01b2019a6c10a1361769542203f6fedc5179680" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http", + "httparse", + "log", + "mime", + "spin 0.9.2", + "tokio", + "tokio-util", + "twoway", + "version_check", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg 1.0.1", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg 1.0.1", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "ordermap" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" + +[[package]] +name = "os_str_bytes" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85" + +[[package]] +name = "parking_lot" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.9", + "smallvec", + "winapi", +] + +[[package]] +name = "pear" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e44241c5e4c868e3eaa78b7c1848cadd6344ed4f54d029832d32b415a58702" +dependencies = [ + "inlinable_string", + "pear_codegen", + "yansi", +] + +[[package]] +name = "pear_codegen" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82a5ca643c2303ecb740d506539deba189e16f2754040a42901cd8105d0282d0" +dependencies = [ + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "petgraph" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" +dependencies = [ + "fixedbitset", + "ordermap", +] + +[[package]] +name = "phf_generator" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" +dependencies = [ + "phf_shared", + "rand 0.6.5", +] + +[[package]] +name = "phf_shared" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[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", + "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]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + +[[package]] +name = "proc-macro2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +dependencies = [ + "unicode-xid 0.2.2", +] + +[[package]] +name = "proc-macro2-diagnostics" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "version_check", + "yansi", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.7", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +dependencies = [ + "getrandom 0.1.16", + "redox_syscall 0.1.57", + "rust-argon2", +] + +[[package]] +name = "ref-cast" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300f2a835d808734ee295d45007adacb9ebb29dd3ae2424acfa17930cae541da" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "reqwest" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246e9f61b9bb77df069a947682be06e31ac43ea37862e244a69f177694ea6d22" +dependencies = [ + "async-compression", + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "lazy_static", + "log", + "mime", + "percent-encoding", + "pin-project-lite", + "rustls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-rustls", + "tokio-util", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rocket" +version = "0.5.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a71c18c42a0eb15bf3816831caf0dad11e7966f2a41aaf486a701979c4dd1f2" +dependencies = [ + "async-stream", + "async-trait", + "atomic", + "atty", + "binascii", + "bytes", + "either", + "figment", + "futures", + "indexmap", + "log", + "memchr", + "multer", + "num_cpus", + "parking_lot", + "pin-project-lite", + "rand 0.8.4", + "ref-cast", + "rocket_codegen", + "rocket_http", + "serde", + "state", + "tempfile", + "time 0.2.27", + "tokio", + "tokio-stream", + "tokio-util", + "ubyte", + "version_check", + "yansi", +] + +[[package]] +name = "rocket_codegen" +version = "0.5.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66f5fa462f7eb958bba8710c17c5d774bbbd59809fa76fb1957af7e545aea8bb" +dependencies = [ + "devise", + "glob", + "indexmap", + "proc-macro2", + "quote", + "rocket_http", + "syn", + "unicode-xid 0.2.2", +] + +[[package]] +name = "rocket_http" +version = "0.5.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c8b7d512d2fcac2316ebe590cde67573844b99e6cc9ee0f53375fa16e25ebd" +dependencies = [ + "cookie", + "either", + "http", + "hyper", + "indexmap", + "log", + "memchr", + "mime", + "parking_lot", + "pear", + "percent-encoding", + "pin-project-lite", + "ref-cast", + "serde", + "smallvec", + "stable-pattern", + "state", + "time 0.2.27", + "tokio", + "uncased", +] + +[[package]] +name = "rust-argon2" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" +dependencies = [ + "base64", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64", + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "rustversion" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" + +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", +] + +[[package]] +name = "shitter" +version = "0.1.0" +dependencies = [ + "clap", + "parking_lot", + "reqwest", + "rocket", + "serde", + "serde_json", + "stderrlog", + "thiserror", + "tokio", + "typed-html", + "url", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "siphasher" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" + +[[package]] +name = "slab" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "socket2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5" + +[[package]] +name = "stable-pattern" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" +dependencies = [ + "memchr", +] + +[[package]] +name = "standback" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" +dependencies = [ + "version_check", +] + +[[package]] +name = "state" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cf4f5369e6d3044b5e365c9690f451516ac8f0954084622b49ea3fde2f6de5" +dependencies = [ + "loom", +] + +[[package]] +name = "stderrlog" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a53e2eff3e94a019afa6265e8ee04cb05b9d33fe9f5078b14e4e391d155a38" +dependencies = [ + "atty", + "chrono", + "log", + "termcolor", + "thread_local", +] + +[[package]] +name = "stdweb" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" +dependencies = [ + "discard", + "rustc_version", + "stdweb-derive", + "stdweb-internal-macros", + "stdweb-internal-runtime", + "wasm-bindgen", +] + +[[package]] +name = "stdweb-derive" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "stdweb-internal-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" +dependencies = [ + "base-x", + "proc-macro2", + "quote", + "serde", + "serde_derive", + "serde_json", + "sha1", + "syn", +] + +[[package]] +name = "stdweb-internal-runtime" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" + +[[package]] +name = "string_cache" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89c058a82f9fd69b1becf8c274f412281038877c553182f1d02eb027045a2d67" +dependencies = [ + "lazy_static", + "new_debug_unreachable", + "phf_shared", + "precomputed-hash", + "serde", + "string_cache_codegen", + "string_cache_shared", +] + +[[package]] +name = "string_cache_codegen" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f45ed1b65bf9a4bf2f7b7dc59212d1926e9eaf00fa998988e420fd124467c6" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "string_cache_shared", +] + +[[package]] +name = "string_cache_shared" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b" + +[[package]] +name = "strum_macros" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid 0.2.2", +] + +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if", + "libc", + "rand 0.8.4", + "redox_syscall 0.2.9", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "term" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" +dependencies = [ + "byteorder", + "dirs", + "winapi", +] + +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "time" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" +dependencies = [ + "const_fn", + "libc", + "standback", + "stdweb", + "time-macros", + "version_check", + "winapi", +] + +[[package]] +name = "time-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" +dependencies = [ + "proc-macro-hack", + "time-macros-impl", +] + +[[package]] +name = "time-macros-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "standback", + "syn", +] + +[[package]] +name = "tinyvec" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b7b349f11a7047e6d1276853e612d152f5e8a352c61917887cc2169e2366b4c" +dependencies = [ + "autocfg 1.0.1", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "once_cell", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-stream" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2f3f698253f03119ac0102beaa64f67a67e08074d03a22d18784104543727f" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tower-service" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" + +[[package]] +name = "tracing" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "twoway" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c57ffb460d7c24cd6eda43694110189030a3d1dfe418416d9468fd1c1d290b47" +dependencies = [ + "memchr", + "unchecked-index", +] + +[[package]] +name = "typed-html" +version = "0.2.2" +source = "git+https://github.com/bodil/typed-html?rev=d95ce1a2930f2385d4f3765d061dbeff3503107f#d95ce1a2930f2385d4f3765d061dbeff3503107f" +dependencies = [ + "htmlescape", + "language-tags", + "mime", + "proc-macro-hack", + "proc-macro-nested", + "strum", + "strum_macros", + "typed-html-macros", +] + +[[package]] +name = "typed-html-macros" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44a4dba17ed65147f4780560f1078de857f3f4d48f5aeb2197bace8e103a7356" +dependencies = [ + "ansi_term", + "lalrpop", + "lalrpop-util", + "proc-macro-hack", + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "typenum" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" + +[[package]] +name = "ubyte" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42756bb9e708855de2f8a98195643dff31a97f0485d90d8467b39dc24be9e8fe" +dependencies = [ + "serde", +] + +[[package]] +name = "uncased" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baeed7327e25054889b9bd4f975f32e5f4c5d434042d59ab6cd4142c0a76ed0" +dependencies = [ + "serde", + "version_check", +] + +[[package]] +name = "unchecked-index" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" + +[[package]] +name = "unicode-bidi" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0" +dependencies = [ + "matches", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b608ecc8f4198fe8680e2ed18eccab5f0cd4caaf3d83516fa5fb2e927fda2586" +dependencies = [ + "cfg-if", + "serde", + "serde_json", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "580aa3a91a63d23aac5b6b267e2d13cb4f363e31dce6c352fca4752ae12e479f" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16646b21c3add8e13fdb8f20172f8a28c3dbf62f45406bcff0233188226cfe0c" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171ebf0ed9e1458810dfcb31f2e766ad6b3a89dbda42d8901f2b268277e5f09c" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c2657dd393f03aa2a659c25c6ae18a13a4048cebd220e147933ea837efc589f" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e0c4a743a309662d45f4ede961d7afa4ba4131a59a639f29b0069c3798bbcc2" + +[[package]] +name = "web-sys" +version = "0.3.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c70a82d842c9979078c772d4a1344685045f1a5628f677c2b2eab4dd7d2696" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" +dependencies = [ + "webpki", +] + +[[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-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[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]] +name = "winreg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +dependencies = [ + "winapi", +] + +[[package]] +name = "yansi" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..882a890 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "shitter" +version = "0.1.0" +edition = "2018" + +[dependencies] +clap = "3.0.0-beta.2" +parking_lot = "0.11.1" +reqwest = { version = "0.11.4", default-features = false, features = ["gzip", "json", "rustls-tls"] } +rocket = "0.5.0-rc.1" +serde = { version = "1.0.126", features = ["derive"] } +serde_json = "1.0.64" +stderrlog = "0.5.1" +thiserror = "1.0.26" +tokio = { version = "1.9.0", features = ["full"] } +typed-html = { git = "https://github.com/bodil/typed-html", rev = "d95ce1a2930f2385d4f3765d061dbeff3503107f" } +url = "2.2.2" diff --git a/README.md b/README.md new file mode 100644 index 0000000..8c8e08b --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +shitter: Twitter Client +=== + +License: AGPL diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..f5bfddc --- /dev/null +++ b/default.nix @@ -0,0 +1,12 @@ +(import + (let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + in + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } + ) + { + src = ./.; + }).defaultNix \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..4756933 --- /dev/null +++ b/flake.lock @@ -0,0 +1,125 @@ +{ + "nodes": { + "crate2nix": { + "flake": false, + "locked": { + "lastModified": 1627923438, + "narHash": "sha256-/O/FDJynVXOdFhSXQGU2uH/FQF3MS93WMyeY+9fcRaU=", + "owner": "kolloch", + "repo": "crate2nix", + "rev": "29460b5c411defa5e8e0851fe7ecbca0f0fa41d3", + "type": "github" + }, + "original": { + "owner": "kolloch", + "repo": "crate2nix", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1627913399, + "narHash": "sha256-hY8g6H2KFL8ownSiFeMOjwPC8P0ueXpCVEbxgda3pko=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "12c64ca55c1014cdc1b16ed5a804aa8576601ff2", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1614513358, + "narHash": "sha256-LakhOx3S1dRjnh0b5Dg3mbZyH0ToC9I8Y2wKSkBaTzU=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5466c5bbece17adaab2d82fae80b46e807611bf3", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1627978428, + "narHash": "sha256-813SF+K9wEwHVTOhgVpaC3CSZWcjap7Pv3bWppV0U44=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b3ca5f904aa0f3341413f14e3bd8303a6acd39de", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1617325113, + "narHash": "sha256-GksR0nvGxfZ79T91UUtWjjccxazv6Yh/MvEJ82v1Xmw=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "54c1e44240d8a527a8f4892608c4bce5440c3ecb", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "crate2nix": "crate2nix", + "flake-compat": "flake-compat", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay", + "utils": "utils" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1627957145, + "narHash": "sha256-cY5lS2S/RMsC1xFtkcmhLXlVP7ahZoxFeKedkXDvIzY=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "ab6f3086de97980e4fdcb0560921852a407e0b79", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "utils": { + "locked": { + "lastModified": 1623875721, + "narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "f7e004a55b120c02ecb6219596820fcd32ca8772", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..1e53b5e --- /dev/null +++ b/flake.nix @@ -0,0 +1,43 @@ +{ + description = "shitter"; + inputs = { + utils.url = "github:numtide/flake-utils"; + rust-overlay.url = "github:oxalica/rust-overlay"; + crate2nix = { url = "github:kolloch/crate2nix"; flake = false; }; + flake-compat = { url = "github:edolstra/flake-compat"; flake = false; }; + }; + + outputs = { self, nixpkgs, utils, rust-overlay, crate2nix, ... }: + let + name = "shitter"; + rustChannel = "stable"; + in + utils.lib.eachDefaultSystem + (system: + let + pkgs = import nixpkgs { + inherit system; + overlays = [ + rust-overlay.overlay + (self: super: { + rustc = self.rust-bin.${rustChannel}.latest.default; + cargo = self.rust-bin.${rustChannel}.latest.default; + }) + ]; + }; + inherit (import "${crate2nix}/tools.nix" { inherit pkgs; }) generatedCargoNix; + project = pkgs.callPackage + (generatedCargoNix { inherit name; src = ./.; }) + { defaultCrateOverrides = pkgs.defaultCrateOverrides; }; + buildInputs = with pkgs; []; + in rec { + packages.${name} = project.rootCrate.build; + defaultPackage = packages.${name}; + apps.${name} = utils.lib.mkApp { + inherit name; + drv = packages.${name}; + }; + defaultApp = apps.${name}; + } + ); +} diff --git a/sass/general.scss b/sass/general.scss new file mode 100644 index 0000000..9feb3d3 --- /dev/null +++ b/sass/general.scss @@ -0,0 +1,39 @@ +@import '_variables'; +@import '_mixins'; + +.panel-container { + margin: auto; + font-size: 130%; +} + +.error-panel { + @include center-panel(var(--error_red)); + text-align: center; +} + +.search-bar > form { + @include center-panel(var(--darkest_grey)); + + button { + background: var(--bg_elements); + color: var(--fg_color); + border: 0; + border-radius: 3px; + cursor: pointer; + font-weight: bold; + width: 30px; + height: 30px; + } + + input { + font-size: 16px; + width: 100%; + background: var(--bg_elements); + color: var(--fg_color); + border: 0; + border-radius: 4px; + padding: 4px; + margin-right: 8px; + height: unset; + } +} diff --git a/sass/include/_mixins.css b/sass/include/_mixins.css new file mode 100644 index 0000000..94e11ee --- /dev/null +++ b/sass/include/_mixins.css @@ -0,0 +1,97 @@ +@import '_variables'; + +@mixin panel($width, $max-width) { + max-width: $max-width; + margin: 0 auto; + float: none; + border-radius: 0; + position: relative; + width: $width; +} + +@mixin play-button { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 1; + + &:hover { + .overlay-circle { + border-color: var(--play_button_hover); + } + + .overlay-triangle { + border-color: transparent transparent transparent var(--play_button_hover); + } + } +} + +@mixin breakable { + overflow: hidden; + overflow-wrap: break-word; +} + +@mixin ellipsis { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +@mixin center-panel($bg) { + padding: 12px; + border-radius: 4px; + display: flex; + background: $bg; + box-shadow: 0 0 15px $shadow_dark; + margin: auto; + margin-top: -50px; +} + +@mixin input-colors { + &:hover { + border-color: var(--accent); + } + + &:active { + border-color: var(--accent_light); + } +} + +@mixin search-resize($width, $rows) { + @media(max-width: $width) { + .search-toggles { + grid-template-columns: repeat($rows, auto); + } + + #search-panel-toggle:checked ~ .search-panel { + @if $rows == 6 { + max-height: 200px !important; + } + @if $rows == 5 { + max-height: 300px !important; + } + @if $rows == 4 { + max-height: 300px !important; + } + @if $rows == 3 { + max-height: 365px !important; + } + } + } +} + +@mixin create-toggle($elem, $height) { + ##{$elem}-toggle { + display: none; + + &:checked ~ .#{$elem} { + max-height: $height; + } + + &:checked ~ label .icon-down:before { + transform: rotate(180deg) translateY(-1px); + } + } +} diff --git a/sass/include/_variables.scss b/sass/include/_variables.scss new file mode 100644 index 0000000..0f81235 --- /dev/null +++ b/sass/include/_variables.scss @@ -0,0 +1,44 @@ +// colors +$bg_color: #0F0F0F; +$fg_color: #F8F8F2; +$fg_faded: #F8F8F2CF; +$fg_dark: #FF6C60; +$fg_nav: #FF6C60; + +$bg_panel: #161616; +$bg_elements: #121212; +$bg_overlays: #1F1F1F; +$bg_hover: #1A1A1A; + +$grey: #888889; +$dark_grey: #404040; +$darker_grey: #282828; +$darkest_grey: #222222; +$border_grey: #3E3E35; + +$accent: #FF6C60; +$accent_light: #FFACA0; +$accent_dark: #8A3731; +$accent_border: #FF6C6091; + +$play_button: #D8574D; +$play_button_hover: #FF6C60; + +$more_replies_dots: #AD433B; +$error_red: #420A05; + +$verified_blue: #1DA1F2; +$icon_text: $fg_color; + +$tab: $fg_color; +$tab_selected: $accent; + +$shadow: rgba(0,0,0,.6); +$shadow_dark: rgba(0,0,0,.2); + +//fonts +$font_0: Helvetica Neue; +$font_1: Helvetica; +$font_2: Arial; +$font_3: sans-serif; +$font_4: fontello; diff --git a/sass/index.scss b/sass/index.scss new file mode 100644 index 0000000..9e048b6 --- /dev/null +++ b/sass/index.scss @@ -0,0 +1,164 @@ +@import '_variables'; + +@import 'tweet/_base'; +@import 'profile/_base'; +@import 'general'; +@import 'navbar'; +@import 'inputs'; +@import 'timeline'; +@import 'search'; + +body { + // colors + --bg_color: #{$bg_color}; + --fg_color: #{$fg_color}; + --fg_faded: #{$fg_faded}; + --fg_dark: #{$fg_dark}; + --fg_nav: #{$fg_nav}; + + --bg_panel: #{$bg_panel}; + --bg_elements: #{$bg_elements}; + --bg_overlays: #{$bg_overlays}; + --bg_hover: #{$bg_hover}; + + --grey: #{$grey}; + --dark_grey: #{$dark_grey}; + --darker_grey: #{$darker_grey}; + --darkest_grey: #{$darkest_grey}; + --border_grey: #{$border_grey}; + + --accent: #{$accent}; + --accent_light: #{$accent_light}; + --accent_dark: #{$accent_dark}; + --accent_border: #{$accent_border}; + + --play_button: #{$play_button}; + --play_button_hover: #{$play_button_hover}; + + --more_replies_dots: #{$more_replies_dots}; + --error_red: #{$error_red}; + + --verified_blue: #{$verified_blue}; + --icon_text: #{$icon_text}; + + --tab: #{$fg_color}; + --tab_selected: #{$accent}; + + --profile_stat: #{$fg_color}; + + background-color: var(--bg_color); + color: var(--fg_color); + font-family: $font_0, $font_1, $font_2, $font_3; + font-size: 14px; + line-height: 1.3; + margin: 0; +} + +* { + outline: unset; + margin: 0; + text-decoration: none; +} + +h1 { + display: inline; +} + +h2, h3 { + font-weight: normal; +} + +p { + margin: 14px 0; +} + +a { + color: var(--accent); + + &:hover { + text-decoration: underline; + } +} + +fieldset { + border: 0; + padding: 0; + margin-top: -0.6em; +} + +legend { + width: 100%; + padding: .6em 0 .3em 0; + border: 0; + font-size: 16px; + border-bottom: 1px solid var(--border_grey); + margin-bottom: 8px; +} + +.cookie-note { + border-top: 1px solid var(--border_grey); + border-bottom: 1px solid var(--border_grey); + padding: 6px 0 8px 0; + margin-bottom: 8px; + margin-top: 16px; +} + +ul { + padding-left: 1.3em; +} + +.container { + display: flex; + flex-wrap: wrap; + box-sizing: border-box; + padding-top: 50px; + margin: auto; + min-height: 100vh; +} + +.icon-container { + display: inline; +} + +.overlay-panel { + max-width: 600px; + width: 100%; + margin: 0 auto; + margin-top: 10px; + background-color: var(--bg_overlays); + padding: 10px 15px; + align-self: start; + + ul { + margin-bottom: 14px; + } + + p { + word-break: break-word; + } +} + +.verified-icon { + color: var(--icon_text); + background-color: var(--verified_blue); + border-radius: 50%; + flex-shrink: 0; + margin: 2px 0 3px 3px; + padding-top: 2px; + height: 12px; + width: 14px; + font-size: 8px; + display: inline-block; + text-align: center; + vertical-align: middle; +} + +@media(max-width: 600px) { + .preferences-container { + max-width: 95vw; + } + + .nav-item, .nav-item .icon-container { + font-size: 16px; + } +} diff --git a/sass/inputs.scss b/sass/inputs.scss new file mode 100644 index 0000000..17c2a22 --- /dev/null +++ b/sass/inputs.scss @@ -0,0 +1,185 @@ +@import '_variables'; +@import '_mixins'; + +button { + @include input-colors; + background-color: var(--bg_elements); + color: var(--fg_color); + border: 1px solid var(--accent_border); + padding: 3px 6px; + font-size: 14px; + cursor: pointer; + float: right; +} + +input[type="text"], +input[type="date"], +select { + @include input-colors; + background-color: var(--bg_elements); + padding: 1px 4px; + color: var(--fg_color); + border: 1px solid var(--accent_border); + border-radius: 0; + font-size: 14px; +} + +input[type="text"] { + height: 16px; +} + +select { + height: 20px; + padding: 0 2px; + line-height: 1; +} + +input[type="date"]::-webkit-inner-spin-button { + display: none; +} + +input[type="date"]::-webkit-clear-button { + margin-left: 17px; + filter: grayscale(100%); + filter: hue-rotate(120deg); +} + +input::-webkit-calendar-picker-indicator { + opacity: 0; +} + +input::-webkit-datetime-edit-day-field:focus, +input::-webkit-datetime-edit-month-field:focus, +input::-webkit-datetime-edit-year-field:focus { + background-color: var(--accent); + color: var(--fg_color); + outline: none; +} + +.date-range { + .date-input { + display: inline-block; + position: relative; + } + + .icon-container { + pointer-events: none; + position: absolute; + top: 2px; + right: 5px; + } + + .search-title { + margin: 0 2px; + } +} + +.icon-button button { + color: var(--accent); + text-decoration: none; + background: none; + border: none; + float: none; + padding: unset; + padding-left: 4px; + + &:hover { + color: var(--accent_light); + } +} + +.checkbox { + position: absolute; + top: 1px; + right: 0; + height: 17px; + width: 17px; + background-color: var(--bg_elements); + border: 1px solid var(--accent_border); + + &:after { + content: ""; + position: absolute; + display: none; + } +} + +.checkbox-container { + display: block; + position: relative; + margin-bottom: 5px; + cursor: pointer; + user-select: none; + padding-right: 22px; + + input { + position: absolute; + opacity: 0; + cursor: pointer; + height: 0; + width: 0; + + &:checked ~ .checkbox:after { + display: block; + } + } + + &:hover input ~ .checkbox { + border-color: var(--accent); + } + + &:active input ~ .checkbox { + border-color: var(--accent_light); + } + + .checkbox:after { + left: 2px; + bottom: 0; + font-size: 13px; + font-family: $font_4; + content: '\e803'; + } +} + +.pref-group { + display: inline; +} + +.preferences { + button { + margin: 6px 0 3px 0; + } + + label { + padding-right: 150px; + } + + select { + position: absolute; + top: 0; + right: 0; + display: block; + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + } + + input[type="text"] { + position: absolute; + right: 0; + max-width: 140px; + } + + .pref-group { + display: block; + } + + .pref-input { + position: relative; + margin-bottom: 6px; + } + + .pref-reset { + float: left; + } +} diff --git a/sass/navbar.scss b/sass/navbar.scss new file mode 100644 index 0000000..cf9c80e --- /dev/null +++ b/sass/navbar.scss @@ -0,0 +1,88 @@ +@import '_variables'; + +nav { + display: flex; + align-items: center; + position: fixed; + background-color: var(--bg_overlays); + box-shadow: 0 0 4px $shadow; + padding: 0; + width: 100%; + height: 50px; + z-index: 1000; + font-size: 16px; + + a, .icon-button button { + color: var(--fg_nav); + } +} + +.inner-nav { + margin: auto; + box-sizing: border-box; + padding: 0 10px; + display: flex; + align-items: center; + flex-basis: 920px; + height: 50px; +} + +.site-name { + font-size: 15px; + font-weight: 600; + line-height: 1; + + &:hover { + color: var(--accent_light); + text-decoration: unset; + } +} + +.site-logo { + display: block; + width: 35px; + height: 35px; +} + +.nav-item { + display: flex; + flex: 1; + line-height: 50px; + height: 50px; + overflow: hidden; + flex-wrap: wrap; + align-items: center; + + &.right { + text-align: right; + justify-content: flex-end; + } + + &.right a { + padding-left: 4px; + + &:hover { + color: var(--accent_light); + text-decoration: unset; + } + } +} + +.lp { + height: 14px; + margin-top: 2px; + display: block; + fill: var(--fg_nav); + + &:hover { + fill: var(--accent_light); + } +} + +.icon-info:before { + margin: 0 -3px; +} + +.icon-cog { + font-size: 15px; +} diff --git a/sass/profile/_base.scss b/sass/profile/_base.scss new file mode 100644 index 0000000..23ac4f2 --- /dev/null +++ b/sass/profile/_base.scss @@ -0,0 +1,73 @@ +@import '_variables'; +@import '_mixins'; + +@import 'card'; +@import 'photo-rail'; + +.profile-tabs { + @include panel(auto, 900px); + + .timeline-container { + float: right; + width: 68% !important; + max-width: unset; + } +} + +.profile-banner { + padding-bottom: 4px; + + a { + display: inherit; + line-height: 0; + } + + img { + width: 100%; + } +} + +.profile-banner-color { + width: 100%; + padding-bottom: 25%; +} + +.profile-tab { + padding: 0 4px 0 0; + box-sizing: border-box; + display: inline-block; + font-size: 14px; + text-align: left; + vertical-align: top; + max-width: 32%; + top: 50px; +} + +.profile-result .username { + margin: 0 !important; +} + +.profile-result .tweet-header { + margin-bottom: unset; +} + +@media(max-width: 600px) { + .profile-tabs { + width: 100vw; + + .timeline-container { + width: 100% !important; + + .tab-item wide { + flex-grow: 1.4; + } + } + } + + .profile-tab { + width: 100%; + max-width: unset; + position: initial !important; + padding: 0; + } +} diff --git a/sass/profile/card.scss b/sass/profile/card.scss new file mode 100644 index 0000000..7c44781 --- /dev/null +++ b/sass/profile/card.scss @@ -0,0 +1,124 @@ +@import '_variables'; +@import '_mixins'; + +.profile-card { + flex-wrap: wrap; + background: var(--bg_panel); + padding: 12px; + display: flex; +} + +.profile-card-info { + @include breakable; + width: 100%; +} + +.profile-card-tabs-name { + @include breakable; + max-width: 100%; +} + +.profile-card-username { + @include breakable; + color: var(--fg_color); + font-size: 14px; + display: block; +} + +.profile-card-fullname { + @include breakable; + color: var(--fg_color); + font-size: 16px; + font-weight: bold; + text-shadow: none; + max-width: 100%; +} + +.profile-card-avatar { + display: block; + width: 100%; + padding-bottom: 6px; + margin-right: 4px; + + img { + display: block; + box-sizing: border-box; + width: 100%; + height: 100%; + margin: 0; + border: 4px solid var(--darker_grey); + background: var(--bg_color); + } +} + +.profile-card-extra { + display: contents; + flex: 100%; + margin-top: 7px; + + .profile-bio { + @include breakable; + width: 100%; + margin: 4px -6px 6px 0; + white-space: pre-wrap; + + p { + margin: 0; + } + } + + .profile-joindate, .profile-location, profile-website { + color: var(--fg_faded); + margin: 2px 0; + width: 100%; + } +} + +.profile-card-extra-links { + margin-top: 8px; + font-size: 14px; + width: 100%; +} + +.profile-statlist { + display: flex; + flex-wrap: wrap; + padding: 0; + width: 100%; + justify-content: space-between; + + li { + display: table-cell; + text-align: center; + } +} + +.profile-stat-header { + font-weight: bold; + color: var(--profile_stat); +} + +.profile-stat-num { + display: block; + color: var(--profile_stat); +} + +@media(max-width: 600px) { + .profile-card-info { + display: flex; + } + + .profile-card-tabs-name { + @include breakable; + } + + .profile-card-avatar { + height: 60px; + width: unset; + + img { + border-width: 2px; + width: unset; + } + } +} diff --git a/sass/profile/photo-rail.scss b/sass/profile/photo-rail.scss new file mode 100644 index 0000000..ebe2321 --- /dev/null +++ b/sass/profile/photo-rail.scss @@ -0,0 +1,97 @@ +@import '_variables'; + +.photo-rail { + &-card { + float: left; + background: var(--bg_panel); + border-radius: 0 0 4px 4px; + width: 100%; + margin: 5px 0; + } + + &-header { + padding: 5px 12px 0; + } + + &-header-mobile { + display: none; + box-sizing: border-box; + padding: 5px 12px 0; + width: 100%; + float: unset; + color: var(--accent); + justify-content: space-between; + } + + &-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + grid-gap: 3px 3px; + padding: 5px 12px 12px; + + a { + position: relative; + border-radius: 5px; + + &:before { + content: ""; + display: block; + padding-top: 100%; + } + } + + img { + height: 100%; + width: 100%; + border-radius: 4px; + object-fit: cover; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + } + } +} + +@include create-toggle(photo-rail-grid, 640px); +#photo-rail-grid-toggle:checked ~ .photo-rail-grid { + padding-bottom: 12px; +} + +@media(max-width: 600px) { + .photo-rail-header { + display: none; + } + + .photo-rail-header-mobile { + display: flex; + } + + .photo-rail-grid { + max-height: 0; + padding-bottom: 0; + overflow: hidden; + transition: max-height 0.4s; + } +} + +@media(max-width: 600px) { + .photo-rail-grid { + grid-template-columns: repeat(6, 1fr); + } + + #photo-rail-grid-toggle:checked ~ .photo-rail-grid { + max-height: 300px; + } +} + +@media(max-width: 450px) { + .photo-rail-grid { + grid-template-columns: repeat(4, 1fr); + } + + #photo-rail-grid-toggle:checked ~ .photo-rail-grid { + max-height: 450px; + } +} diff --git a/sass/search.scss b/sass/search.scss new file mode 100644 index 0000000..0311fb0 --- /dev/null +++ b/sass/search.scss @@ -0,0 +1,120 @@ +@import '_variables'; +@import '_mixins'; + +.search-title { + font-weight: bold; + display: inline-block; + margin-top: 4px; +} + +.search-field { + display: flex; + flex-wrap: wrap; + + button { + margin: 0 2px 0 0; + height: 23px; + } + + .pref-input { + margin: 0 4px 0 0; + flex-grow: 1; + height: 23px; + } + + input[type="text"] { + height: calc(100% - 4px); + width: calc(100% - 8px); + } + + > label { + display: inline; + background-color: var(--bg_elements); + color: var(--fg_color); + border: 1px solid var(--accent_border); + padding: 1px 6px 2px 6px; + font-size: 14px; + cursor: pointer; + margin-bottom: 2px; + + @include input-colors; + } + + @include create-toggle(search-panel, 200px); +} + +.search-panel { + width: 100%; + max-height: 0; + overflow: hidden; + transition: max-height 0.4s; + + flex-grow: 1; + font-weight: initial; + text-align: left; + + > div { + line-height: 1.7em; + } + + .checkbox-container { + display: inline; + padding-right: unset; + margin-bottom: unset; + margin-left: 23px; + } + + .checkbox { + right: unset; + left: -22px; + } + + .checkbox-container .checkbox:after { + top: -4px; + } +} + +.search-row { + display: flex; + flex-wrap: wrap; + line-height: unset; + + > div { + flex-grow: 1; + flex-shrink: 1; + } + + input { + height: 21px; + } + + .pref-input { + display: block; + padding-bottom: 5px; + + input { + height: 21px; + margin-top: 1px; + } + } +} + +.search-toggles { + flex-grow: 1; + display: grid; + grid-template-columns: repeat(6, auto); + grid-column-gap: 10px; +} + +.profile-tabs { + @include search-resize(820px, 5); + @include search-resize(725px, 4); + @include search-resize(600px, 6); + @include search-resize(560px, 5); + @include search-resize(480px, 4); + @include search-resize(410px, 3); +} + +@include search-resize(560px, 5); +@include search-resize(480px, 4); +@include search-resize(410px, 3); diff --git a/sass/timeline.scss b/sass/timeline.scss new file mode 100644 index 0000000..db19bed --- /dev/null +++ b/sass/timeline.scss @@ -0,0 +1,161 @@ +@import '_variables'; + +.timeline-container { + @include panel(100%, 600px); +} + +.timeline { + background-color: var(--bg_panel); + + > div:not(:first-child) { + border-top: 1px solid var(--border_grey); + } +} + +.timeline-header { + width: 100%; + background-color: var(--bg_panel); + text-align: center; + padding: 8px; + display: block; + font-weight: bold; + margin-bottom: 5px; + box-sizing: border-box; + + button { + float: unset; + } +} + +.timeline-banner img { + width: 100%; +} + +.timeline-description { + font-weight: normal; +} + +.tab { + align-items: center; + display: flex; + flex-wrap: wrap; + list-style: none; + margin: 0 0 5px 0; + background-color: var(--bg_panel); + padding: 0; +} + +.tab-item { + flex: 1 1 0; + text-align: center; + margin-top: 0; + + a { + border-bottom: .1rem solid transparent; + color: var(--tab); + display: block; + padding: 8px 0; + text-decoration: none; + font-weight: bold; + + &:hover { + text-decoration: none; + } + + &.active { + border-bottom-color: var(--tab_selected); + color: var(--tab_selected); + } + } + + &.active a { + border-bottom-color: var(--tab_selected); + color: var(--tab_selected); + } + + &.wide { + flex-grow: 1.2; + } +} + +.timeline-footer { + background-color: var(--bg_panel); + padding: 6px 0; +} + +.timeline-protected { + text-align: center; + + p { + margin: 8px 0; + } + + h2 { + color: var(--accent); + font-size: 20px; + font-weight: 600; + } +} + +.timeline-none { + color: var(--accent); + font-size: 20px; + font-weight: 600; + text-align: center; +} + +.timeline-end { + background-color: var(--bg_panel); + color: var(--accent); + font-size: 16px; + font-weight: 600; + text-align: center; +} + +.show-more { + background-color: var(--bg_panel); + text-align: center; + padding: .75em 0; + display: block !important; + + a { + background-color: var(--darkest_grey); + display: inline-block; + height: 2em; + padding: 0 2em; + line-height: 2em; + + &:hover { + background-color: var(--darker_grey); + } + } +} + +.top-ref { + background-color: var(--bg_color); + border-top: none !important; + + .icon-down { + font-size: 20px; + display: flex; + justify-content: center; + text-decoration: none; + + &:hover { + color: var(--accent_light); + } + + &::before { + transform: rotate(180deg) translateY(-1px); + } + } +} + +.timeline-item { + overflow-wrap: break-word; + border-left-width: 0; + min-width: 0; + padding: .75em; + display: flex; + position: relative; +} diff --git a/sass/tweet/_base.scss b/sass/tweet/_base.scss new file mode 100644 index 0000000..9ac86e9 --- /dev/null +++ b/sass/tweet/_base.scss @@ -0,0 +1,205 @@ +@import '_variables'; +@import '_mixins'; +@import 'thread'; +@import 'media'; +@import 'video'; +@import 'embed'; +@import 'card'; +@import 'poll'; +@import 'quote'; + +.tweet-body { + flex: 1; + min-width: 0; + margin-left: 58px; + pointer-events: none; + z-index: 1; +} + +.tweet-content { + font-family: $font_3; + line-height: 1.3em; + pointer-events: all; + display: inline; +} + +.tweet-bidi { + display: block !important; +} + +.tweet-header { + padding: 0; + vertical-align: bottom; + flex-basis: 100%; + margin-bottom: .2em; + + a { + display: inline-block; + word-break: break-all; + max-width: 100%; + pointer-events: all; + } +} + +.tweet-name-row { + padding: 0; + display: flex; + justify-content: space-between; +} + +.fullname-and-username { + display: flex; + min-width: 0; +} + +.fullname { + @include ellipsis; + flex-shrink: 2; + max-width: 80%; + font-size: 14px; + font-weight: 700; + color: var(--fg_color); +} + +.username { + @include ellipsis; + min-width: 1.6em; + margin-left: .4em; + word-wrap: normal; +} + +.tweet-date { + display: flex; + flex-shrink: 0; + margin-left: 4px; +} + +.tweet-date a, .username, .show-more a { + color: var(--fg_dark); +} + +.tweet-published { + margin: 0; + margin-top: 5px; + color: var(--grey); + pointer-events: all; +} + +.tweet-avatar { + display: contents !important; + + img { + float: left; + margin-top: 3px; + margin-left: -58px; + width: 48px; + height: 48px; + } +} + +.avatar { + border-radius: 50%; +} + +.avatar.mini { + margin-right: 5px; + margin-top: -1px; + width: 20px; + height: 20px; +} + +.attribution { + display: flex; + pointer-events: all; + margin: 5px 0; + + strong { + color: var(--fg_color); + } +} + +.media-tag-block { + padding-top: 5px; + pointer-events: all; + color: var(--fg_faded); + + .icon-container { + padding-right: 2px; + } + + .media-tag, .icon-container { + color: var(--fg_faded); + } +} + +.timeline-container .media-tag-block { + font-size: 13px; +} + +.tweet-geo { + color: var(--fg_faded); +} + +.replying-to { + color: var(--fg_faded); + margin: -2px 0 4px; + + a { + pointer-events: all; + } +} + +.retweet-header, .pinned, .tweet-stats { + align-content: center; + color: var(--grey); + display: flex; + flex-shrink: 0; + flex-wrap: wrap; + font-size: 14px; + font-weight: 600; + line-height: 22px; + + span { + @include ellipsis; + } +} + +.retweet-header { + margin-top: -5px !important; +} + +.tweet-stats { + margin-bottom: -3px; +} + +.tweet-stat { + padding-top: 5px; + padding-right: 8px; +} + +.show-thread { + display: block; + pointer-events: all; + padding-top: 2px; +} + +.unavailable-box { + width: 100%; + height: 100%; + padding: 12px; + border: solid 1px var(--dark_grey); + border-radius: 10px; + background-color: var(--bg_color); +} + +.tweet-link { + height: 100%; + width: 100%; + left: 0; + top: 0; + position: absolute; + + &:hover { + background-color: var(--bg_hover); + } +} diff --git a/sass/tweet/card.scss b/sass/tweet/card.scss new file mode 100644 index 0000000..6d9c20e --- /dev/null +++ b/sass/tweet/card.scss @@ -0,0 +1,118 @@ +@import '_variables'; +@import '_mixins'; + +.card { + margin: 5px 0; + pointer-events: all; + max-height: unset; +} + +.card-container { + border-radius: 10px; + border-width: 1px; + border-style: solid; + border-color: var(--dark_grey); + background-color: var(--bg_elements); + overflow: hidden; + color: inherit; + display: flex; + flex-direction: row; + text-decoration: none !important; + + &:hover { + border-color: var(--grey); + } + + .attachments { + margin: 0; + border-radius: 0; + } +} + +.card-content { + padding: 0.5em; +} + +.card-title { + @include ellipsis; + white-space: unset; + font-weight: bold; + font-size: 1.15em; +} + +.card-description { + margin: 0.3em 0; +} + +.card-destination { + @include ellipsis; + color: var(--grey); + display: block; +} + +.card-content-container { + color: unset; + overflow: auto; + &:hover { + text-decoration: none; + } +} + +.card-image-container { + width: 98px; + flex-shrink: 0; + position: relative; + overflow: hidden; + &:before { + content: ""; + display: block; + padding-top: 100%; + } +} + +.card-image { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + background-color: var(--bg_overlays); + + img { + width: 100%; + height: 100%; + max-height: 400px; + display: block; + object-fit: cover; + } +} + +.card-overlay { + @include play-button; + opacity: 0.8; + display: flex; + justify-content: center; + align-items: center; +} + +.large { + .card-container { + display: block; + } + + .card-image-container { + width: unset; + + &:before { + display: none; + } + } + + .card-image { + position: unset; + border-style: solid; + border-color: var(--dark_grey); + border-width: 0; + border-bottom-width: 1px; + } +} diff --git a/sass/tweet/embed.scss b/sass/tweet/embed.scss new file mode 100644 index 0000000..227fc5e --- /dev/null +++ b/sass/tweet/embed.scss @@ -0,0 +1,17 @@ +@import '_variables'; +@import '_mixins'; + +.embed-video { + .gallery-video { + width: 100%; + height: 100%; + position: absolute; + background-color: black; + top: 0%; + left: 0%; + } + + .video-container { + max-height: unset; + } +} diff --git a/sass/tweet/media.scss b/sass/tweet/media.scss new file mode 100644 index 0000000..91c9dab --- /dev/null +++ b/sass/tweet/media.scss @@ -0,0 +1,119 @@ +@import '_variables'; + +.gallery-row { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + align-items: center; + overflow: hidden; + flex-grow: 1; + max-height: 379.5px; + max-width: 533px; + pointer-events: all; + + .still-image { + width: 100%; + display: flex; + } +} + +.attachments { + margin-top: .35em; + display: flex; + flex-direction: row; + width: 100%; + max-height: 600px; + border-radius: 7px; + overflow: hidden; + flex-flow: column; + background-color: var(--bg_color); + align-items: center; + pointer-events: all; + + .image-attachment { + width: 100%; + } +} + +.attachment { + position: relative; + line-height: 0; + overflow: hidden; + margin: 0 .25em 0 0; + flex-grow: 1; + box-sizing: border-box; + min-width: 2em; + + &:last-child { + margin: 0; + max-height: 530px; + } +} + +.gallery-gif video { + max-height: 530px; + background-color: #101010; +} + +.still-image { + max-height: 379.5px; + max-width: 533px; + justify-content: center; + + img { + object-fit: cover; + max-width: 100%; + max-height: 379.5px; + flex-basis: 300px; + flex-grow: 1; + } +} + +.image { + display: inline-block; +} + +// .single-image { +// display: inline-block; +// width: 100%; +// max-height: 600px; + +// .attachments { +// width: unset; +// max-height: unset; +// display: inherit; +// } +// } + +.overlay-circle { + border-radius: 50%; + background-color: var(--dark_grey); + width: 40px; + height: 40px; + align-items: center; + display: flex; + border-width: 5px; + border-color: var(--play_button); + border-style: solid; +} + +.overlay-triangle { + width: 0; + height: 0; + border-style: solid; + border-width: 12px 0 12px 17px; + border-color: transparent transparent transparent var(--play_button); + margin-left: 14px; +} + +.media-gif { + display: table; + background-color: unset; + width: unset; +} + +.media-body { + flex: 1; + padding: 0; + white-space: pre-wrap; +} diff --git a/sass/tweet/poll.scss b/sass/tweet/poll.scss new file mode 100644 index 0000000..57590c8 --- /dev/null +++ b/sass/tweet/poll.scss @@ -0,0 +1,42 @@ +@import '_variables'; + +.poll-meter { + overflow: hidden; + position: relative; + margin: 6px 0; + height: 26px; + background: var(--bg_color); + border-radius: 5px; + display: flex; + align-items: center; +} + +.poll-choice-bar { + height: 100%; + position: absolute; + background: var(--dark_grey); +} + +.poll-choice-value { + position: relative; + font-weight: bold; + margin-left: 5px; + margin-right: 6px; + min-width: 30px; + text-align: right; + pointer-events: all; +} + +.poll-choice-option { + position: relative; + pointer-events: all; +} + +.poll-info { + color: var(--grey); + pointer-events: all; +} + +.leader .poll-choice-bar { + background: var(--accent_dark); +} diff --git a/sass/tweet/quote.scss b/sass/tweet/quote.scss new file mode 100644 index 0000000..b4bc60e --- /dev/null +++ b/sass/tweet/quote.scss @@ -0,0 +1,94 @@ +@import '_variables'; + +.quote { + margin-top: 10px; + border: solid 1px var(--dark_grey); + border-radius: 10px; + background-color: var(--bg_elements); + overflow: hidden; + pointer-events: all; + position: relative; + width: 100%; + + &:hover { + border-color: var(--grey); + } + + &.unavailable:hover { + border-color: var(--dark_grey); + } + + .tweet-name-row { + padding: 6px 8px; + margin-top: 1px; + } + + .quote-text { + overflow: hidden; + white-space: pre-wrap; + word-wrap: break-word; + padding: 0px 8px 8px 8px; + } + + .show-thread { + padding: 0px 8px 6px 8px; + margin-top: -6px; + } + + .replying-to { + padding: 0px 8px; + margin: unset; + } +} + +.unavailable-quote { + padding: 12px; +} + +.quote-link { + width: 100%; + height: 100%; + left: 0; + top: 0; + position: absolute; +} + +.quote-media-container { + max-height: 300px; + display: flex; + + .card { + margin: unset; + } + + .attachments { + border-radius: 0; + } + + .media-gif { + width: 100%; + display: flex; + justify-content: center; + } + + .gallery-gif .attachment { + display: flex; + justify-content: center; + background-color: var(--bg_color); + + video { + height: unset; + width: unset; + max-height: 100%; + max-width: 100%; + } + } + + .gallery-video, .gallery-gif { + max-height: 300px; + } + + .still-image img { + max-height: 250px + } +} diff --git a/sass/tweet/thread.scss b/sass/tweet/thread.scss new file mode 100644 index 0000000..f8ad603 --- /dev/null +++ b/sass/tweet/thread.scss @@ -0,0 +1,113 @@ +@import '_variables'; +@import '_mixins'; + +.conversation { + @include panel(100%, 600px); + + .show-more { + margin-bottom: 10px; + } +} + +.main-thread { + margin-bottom: 20px; + background-color: var(--bg_panel); +} + +.main-tweet, .replies { + padding-top: 50px; + margin-top: -50px; +} + +.main-tweet .tweet-content { + font-size: 18px; +} + + +@media(max-width: 600px) { + .main-tweet .tweet-content { + font-size: 16px; + } +} + +.reply { + background-color: var(--bg_panel); + margin-bottom: 10px; +} + +.thread-line { + .timeline-item::before, + &.timeline-item::before { + background: var(--accent_dark); + content: ''; + position: relative; + min-width: 3px; + width: 3px; + left: 26px; + border-radius: 2px; + margin-left: -3px; + margin-bottom: 37px; + top: 56px; + z-index: 1; + pointer-events: none; + } + + .with-header:not(:first-child)::after { + background: var(--accent_dark); + content: ''; + position: relative; + float: left; + min-width: 3px; + width: 3px; + right: calc(100% - 26px); + border-radius: 2px; + margin-left: -3px; + margin-bottom: 37px; + bottom: 10px; + height: 30px; + z-index: 1; + pointer-events: none; + } + + .unavailable::before { + top: 48px; + margin-bottom: 28px; + } + + .more-replies::before { + content: '...'; + background: unset; + color: var(--more_replies_dots); + font-weight: bold; + font-size: 20px; + line-height: 0.25em; + left: 1.2em; + width: 5px; + top: 2px; + margin-bottom: 0; + margin-left: -2.5px; + } + + .earlier-replies { + padding-bottom: 0; + margin-bottom: -5px; + } +} + +.timeline-item.thread-last::before { + background: unset; + min-width: unset; + width: 0; + margin: 0; +} + +.more-replies { + padding-top: 0.3em !important; +} + +.more-replies-text { + @include ellipsis; + display: block; + margin-left: 58px; + padding: 7px 0; +} diff --git a/sass/tweet/video.scss b/sass/tweet/video.scss new file mode 100644 index 0000000..3439fe8 --- /dev/null +++ b/sass/tweet/video.scss @@ -0,0 +1,63 @@ +@import '_variables'; +@import '_mixins'; + +video { + height: 100%; + width: 100%; +} + +.gallery-video { + display: flex; + overflow: hidden; +} + +.gallery-video.card-container { + flex-direction: column; +} + +.video-container { + max-height: 530px; + margin: 0; + + img { + height: 100%; + width: 100%; + } +} + +.video-overlay { + @include play-button; + background-color: $shadow; + + p { + position: relative; + z-index: 0; + text-align: center; + top: calc(50% - 20px); + font-size: 20px; + line-height: 1.3; + margin: 0 20px; + } + + div { + position: relative; + z-index: 0; + top: calc(50% - 20px); + margin: 0 auto; + width: 40px; + height: 40px; + } + + form { + width: 100%; + height: 100%; + align-items: center; + justify-content: center; + display: flex; + } + + button { + padding: 5px 8px; + font-size: 16px; + } +} diff --git a/scripts/generate_scss.sh b/scripts/generate_scss.sh new file mode 100644 index 0000000..8fdab6b --- /dev/null +++ b/scripts/generate_scss.sh @@ -0,0 +1,2 @@ +#!/bin/bash +sassc -Isass/include sass/index.scss static/css/style.css diff --git a/src/api/mod.rs b/src/api/mod.rs new file mode 100644 index 0000000..ad5ce9c --- /dev/null +++ b/src/api/mod.rs @@ -0,0 +1,70 @@ +pub mod profile; +pub mod timeline; +mod token; + +use std::fmt::Debug; +use std::time::Duration; + +use reqwest::Url; +use serde::Deserialize; +use tokio::sync::RwLock; + +use crate::consts::*; +use crate::errors::Result; + +use self::token::Token; + +pub struct Api { + client: reqwest::Client, + token: RwLock>, +} + +impl Api { + pub fn new() -> Result { + let client = reqwest::ClientBuilder::new() + .gzip(true) + .use_rustls_tls() + .timeout(Duration::new(15, 0)) + .referer(false) + .build()?; + let token = RwLock::new(None); + Ok(Api { client, token }) + } + + async fn fetch(&self, url: Url) -> Result + where + T: for<'de> Deserialize<'de> + Debug, + { + let token = self.get_token().await?; + + println!("fetching from {}", url); + + use std::{fs::File, io::Write}; + let mut file = File::create(format!("fetched-{}.json", url.as_str().replace("/", "-")))?; + + let resp = self + .client + .get(url) + .header("Connection", "keep-alive") + .header("Authorization", AUTH) + .header("Content-Type", "application/json") + .header("X-Guest-Token", &token.token) + .header("X-Twitter-Active-User", "yes") + .header("Authority", "api.twitter.com") + .header("Accept-Language", "en-US,en;q=0.9") + .header("Accept", "*/*") + .header("DNT", "1") + .send() + .await?; + let text = resp.text().await?; + println!("text: {:?}", text); + + file.write(text.as_bytes())?; + std::mem::drop(file); + + let body: T = serde_json::from_str(&text)?; + println!("body: {:?}", body); + + Ok(body) + } +} diff --git a/src/api/profile.rs b/src/api/profile.rs new file mode 100644 index 0000000..284afe2 --- /dev/null +++ b/src/api/profile.rs @@ -0,0 +1,38 @@ +use reqwest::Url; + +use crate::consts::*; +use crate::errors::Result; + +use super::Api; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Profile { + #[serde(rename = "id_str")] + pub id: String, + pub name: String, + pub screen_name: String, + pub location: String, + pub description: String, + pub url: String, + pub followers_count: usize, + pub friends_count: usize, + #[serde(rename = "favourites_count")] + pub likes_count: usize, + #[serde(rename = "statuses_count")] + pub tweets_count: usize, + pub media_count: usize, + #[serde(skip)] + pub protected: bool, + #[serde(skip)] + pub verified: bool, +} + +impl Api { + pub async fn fetch_profile(&self, username: impl AsRef) -> Result { + let username = username.as_ref(); + let url = Url::parse_with_params(USER_SHOW_URL, &[("screen_name", username)])?; + + let profile = self.fetch::(url).await?; + Ok(profile) + } +} diff --git a/src/api/timeline.rs b/src/api/timeline.rs new file mode 100644 index 0000000..e071c08 --- /dev/null +++ b/src/api/timeline.rs @@ -0,0 +1,58 @@ +use std::collections::HashMap; + +use reqwest::Url; + +use crate::consts::*; +use crate::errors::Result; + +use super::profile::Profile; +use super::Api; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Timeline { + #[serde(rename = "globalObjects")] + pub global_objects: GlobalObjects, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct GlobalObjects { + pub tweets: HashMap, + pub users: HashMap, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Tweet { + #[serde(rename = "id_str")] + pub id: String, + pub created_at: String, + pub text: String, + pub source: String, + #[serde(rename = "user_id_str")] + pub user_id: String, + #[serde(skip)] + pub is_quote_status: bool, + #[serde(rename = "quoted_status_id_str")] + pub quoted_status_id: Option, + pub retweet_count: usize, + #[serde(rename = "favorite_count")] + pub likes_count: usize, + #[serde(rename = "conversation_id_str")] + pub conversation_id: String, +} + +impl Api { + pub async fn fetch_timeline(&self, id: impl AsRef, replies: bool) -> Result { + let id = id.as_ref(); + let replies = match replies { + true => "1", + false => "0", + }; + let url = Url::parse_with_params( + &format!("{}/{}.json", TIMELINE_STUB, id), + &[("userId", id), ("include_tweet_replies", replies)], + )?; + + let timeline = self.fetch::(url).await?; + Ok(timeline) + } +} diff --git a/src/api/token.rs b/src/api/token.rs new file mode 100644 index 0000000..8b40dbb --- /dev/null +++ b/src/api/token.rs @@ -0,0 +1,63 @@ +use std::time::{Duration, Instant}; + +use crate::consts::*; +use crate::errors::Result; + +use super::Api; + +pub const RESET_PERIOD: u64 = 15 * 60; + +#[derive(Clone)] +pub struct Token { + pub token: String, + reset: Instant, +} + +impl Api { + pub async fn get_token(&self) -> Result { + if let Some(current_token) = &*self.token.read().await { + let now = Instant::now(); + if current_token.reset > now { + return Ok(current_token.clone()); + } + } + + let token = self.fetch_token().await?; + *self.token.write().await = Some(token.clone()); + return Ok(token); + } + + async fn fetch_token(&self) -> Result { + let resp = self + .client + .post(ACTIVATE_URL) + .header( + "Accept", + "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", + ) + .header("Accept-Language", "en-US,en;q=0.5") + .header("User-Agent", generate_user_agent()) + .header("Authorization", AUTH) + .send() + .await?; + + #[derive(Deserialize)] + struct Response { + guest_token: String, + } + + let response: Response = resp.json().await?; + let now = Instant::now(); + let reset = now + Duration::new(RESET_PERIOD, 0); + let token = Token { + token: response.guest_token, + reset, + }; + + Ok(token) + } +} + +fn generate_user_agent() -> String { + String::new() +} diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..f8fe10d --- /dev/null +++ b/src/config.rs @@ -0,0 +1,10 @@ +#[derive(Debug, Serialize, Deserialize)] +pub struct Config { + bind_addr: String, + port: u16, + http_max_connections: usize, + + title: String, + hostname: String, + static_dir: String, +} diff --git a/src/consts.rs b/src/consts.rs new file mode 100644 index 0000000..7ddb0eb --- /dev/null +++ b/src/consts.rs @@ -0,0 +1,6 @@ +// TODO: no idea how this was obtained, will check back with twitter developer site later +pub const AUTH: &str = "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA"; + +pub const ACTIVATE_URL: &str = "https://api.twitter.com/1.1/guest/activate.json"; +pub const USER_SHOW_URL: &str = "https://api.twitter.com/1.1/users/show.json"; +pub const TIMELINE_STUB: &str = "https://api.twitter.com/2/timeline/profile"; diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..95b3bdb --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,32 @@ +use rocket::{ + http::Status, + request::Request, + response::{self, Responder, Response}, +}; + +pub type Result = std::result::Result; + +#[derive(Debug, Error)] +pub enum Error { + #[error("rate limit exceeded")] + RateLimitExceeded, + + #[error("reqwest error: {0}")] + Reqwest(#[from] reqwest::Error), + + #[error("url parse error: {0}")] + UrlParse(#[from] url::ParseError), + + #[error("serde_json error: {0}")] + Json(#[from] serde_json::Error), + + #[error("generic io error: {0}")] + Io(#[from] std::io::Error), +} + +impl<'r> Responder<'r, 'static> for Error { + fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> { + error!("Error: {:?}", self); + Response::build().status(Status::InternalServerError).ok() + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..ba97d74 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,57 @@ +#![doc = include_str!("../README.md")] +#![recursion_limit = "512"] + +#[macro_use] +extern crate serde; +#[macro_use] +extern crate rocket; +#[macro_use] +extern crate thiserror; +#[macro_use] +extern crate typed_html; + +mod api; +mod config; +mod consts; +mod errors; +mod render; +mod routes; +mod views; + +use clap::Clap; +use rocket::fs::{FileServer, relative}; + +use crate::api::Api; + +#[derive(Clap)] +struct Opt { + #[clap(short = 'v', long = "verbose", parse(from_occurrences))] + verbose: usize, +} + +#[get("/favicon.ico")] +fn favicon() {} + +#[launch] +fn rocket() -> _ { + let opt = Opt::parse(); + // stderrlog::new() + // .module(module_path!()) + // .verbosity(opt.verbose) + // .init() + // .unwrap(); + + use routes::timeline; + let api = Api::new().unwrap(); + rocket::build() + .mount("/static", FileServer::from(relative!("/static"))) + .mount( + "/", + routes![ + favicon, + timeline::fetch_single_timeline, + timeline::fetch_single_timeline_tab, + ], + ) + .manage(api) +} diff --git a/src/render.rs b/src/render.rs new file mode 100644 index 0000000..925e818 --- /dev/null +++ b/src/render.rs @@ -0,0 +1 @@ +pub fn render_main() {} diff --git a/src/routes/mod.rs b/src/routes/mod.rs new file mode 100644 index 0000000..374271b --- /dev/null +++ b/src/routes/mod.rs @@ -0,0 +1 @@ +pub mod timeline; diff --git a/src/routes/timeline.rs b/src/routes/timeline.rs new file mode 100644 index 0000000..e34bc1e --- /dev/null +++ b/src/routes/timeline.rs @@ -0,0 +1,68 @@ +use rocket::{request::FromParam, State, response::content}; +use typed_html::dom::DOMTree; + +use crate::api::Api; +use crate::errors::Result; +use crate::views::timeline as view; + +pub type FetchSingleTimelineReturn = Result>; + +#[get("/")] +pub async fn fetch_single_timeline(api: &State, name: String) -> FetchSingleTimelineReturn { + fetch_single_timeline_private(api, name, Tab::Main).await +} + +#[get("//")] +pub async fn fetch_single_timeline_tab( + api: &State, + name: String, + tab: Tab, +) -> FetchSingleTimelineReturn { + fetch_single_timeline_private(api, name, tab).await +} + +async fn fetch_single_timeline_private( + api: &State, + name: String, + _tab: Tab, +) -> FetchSingleTimelineReturn { + let profile = api.fetch_profile(name).await?; + + let timeline = api.fetch_timeline(profile.id, false).await?; + println!("timeline: {:?}", timeline); + + let rendered: DOMTree = html!( + + + "shitter" + + + + { view::render_timeline_tweets(timeline.global_objects.tweets.values()) } + + + ); + + Ok(content::Html(rendered.to_string())) +} + +#[derive(Debug)] +pub enum Tab { + Main, + WithReplies, + Media, + Search, +} + +impl<'a> FromParam<'a> for Tab { + type Error = (); + fn from_param(string: &'a str) -> Result { + match string.to_lowercase().as_str() { + "" => Ok(Tab::Main), + "with_replies" => Ok(Tab::WithReplies), + "media" => Ok(Tab::Media), + "search" => Ok(Tab::Search), + _ => Err(()), + } + } +} diff --git a/src/tokens.rs b/src/tokens.rs new file mode 100644 index 0000000..dbac38e --- /dev/null +++ b/src/tokens.rs @@ -0,0 +1,3 @@ +pub fn get_token() { + +} \ No newline at end of file diff --git a/src/views/mod.rs b/src/views/mod.rs new file mode 100644 index 0000000..93bb7d4 --- /dev/null +++ b/src/views/mod.rs @@ -0,0 +1,19 @@ +pub mod timeline; +pub mod tweet; + +use std::convert::TryInto; + +use typed_html::{ + dom::DOMTree, + types::{Class, SpacedSet}, +}; + +pub fn icon(icon: &str) -> DOMTree { + let class_name = format!("icon-{}", icon); + let class_set: SpacedSet = [class_name.as_str()].try_into().unwrap(); + html! ( +
+ +
+ ) +} diff --git a/src/views/timeline.rs b/src/views/timeline.rs new file mode 100644 index 0000000..e526267 --- /dev/null +++ b/src/views/timeline.rs @@ -0,0 +1,24 @@ +use typed_html::{dom::DOMTree, elements::FlowContent}; + +use crate::api::timeline::Tweet; + +use super::tweet::render_tweet; + +pub fn render_to_top() -> Box> { + html!( +
+ +
+ ) +} + +pub fn render_timeline_tweets<'a>(tweets: impl Iterator) -> Box> { + let tweets_rendered = tweets.map(|tweet| render_tweet(tweet)); + + html!( +
+ { tweets_rendered } + { render_to_top() } +
+ ) +} \ No newline at end of file diff --git a/src/views/tweet.rs b/src/views/tweet.rs new file mode 100644 index 0000000..681ee07 --- /dev/null +++ b/src/views/tweet.rs @@ -0,0 +1,13 @@ +use typed_html::elements::FlowContent; + +use crate::api::timeline::Tweet; + +pub fn render_tweet(tweet: &Tweet) -> Box> { + html!( +
+
+ { text!(&tweet.text) } +
+
+ ) +} diff --git a/static/css/.gitignore b/static/css/.gitignore new file mode 100644 index 0000000..e8c7365 --- /dev/null +++ b/static/css/.gitignore @@ -0,0 +1 @@ +style.css