Add command for writing cell edits over time

This commit is contained in:
Tyler Hallada 2023-11-15 16:59:28 -05:00
parent 9fcac0ce39
commit c931eeca86
7 changed files with 466 additions and 159 deletions

3
.gitignore vendored
View File

@ -5,4 +5,5 @@ plugins
cells cells
mods mods
plugins_data plugins_data
files files
edits_over_time

513
Cargo.lock generated
View File

@ -28,17 +28,6 @@ dependencies = [
"cpufeatures", "cpufeatures",
] ]
[[package]]
name = "ahash"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd"
dependencies = [
"getrandom 0.2.10",
"once_cell",
"version_check",
]
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.6" version = "0.8.6"
@ -127,9 +116,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]] [[package]]
name = "atoi" name = "atoi"
version = "1.0.0" version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
dependencies = [ dependencies = [
"num-traits 0.2.17", "num-traits 0.2.17",
] ]
@ -155,12 +144,6 @@ dependencies = [
"rustc-demangle", "rustc-demangle",
] ]
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.21.5" version = "0.21.5"
@ -184,6 +167,9 @@ name = "bitflags"
version = "2.4.1" version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "bitvec" name = "bitvec"
@ -298,6 +284,12 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "const-oid"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
[[package]] [[package]]
name = "constant_time_eq" name = "constant_time_eq"
version = "0.1.5" version = "0.1.5"
@ -425,6 +417,17 @@ dependencies = [
"syn 2.0.38", "syn 2.0.38",
] ]
[[package]]
name = "der"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c"
dependencies = [
"const-oid",
"pem-rfc7468",
"zeroize",
]
[[package]] [[package]]
name = "deranged" name = "deranged"
version = "0.3.9" version = "0.3.9"
@ -454,30 +457,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [ dependencies = [
"block-buffer", "block-buffer",
"const-oid",
"crypto-common", "crypto-common",
"subtle", "subtle",
] ]
[[package]]
name = "dirs"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]] [[package]]
name = "dotenv" name = "dotenv"
version = "0.15.0" version = "0.15.0"
@ -516,6 +500,9 @@ name = "either"
version = "1.9.0" version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "encoding_rs" name = "encoding_rs"
@ -535,6 +522,12 @@ dependencies = [
"num-traits 0.1.43", "num-traits 0.1.43",
] ]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.5" version = "0.3.5"
@ -545,6 +538,17 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "etcetera"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943"
dependencies = [
"cfg-if",
"home",
"windows-sys",
]
[[package]] [[package]]
name = "event-listener" name = "event-listener"
version = "2.5.3" version = "2.5.3"
@ -573,6 +577,17 @@ dependencies = [
"miniz_oxide", "miniz_oxide",
] ]
[[package]]
name = "flume"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
dependencies = [
"futures-core",
"futures-sink",
"spin 0.9.8",
]
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@ -669,13 +684,13 @@ dependencies = [
[[package]] [[package]]
name = "futures-intrusive" name = "futures-intrusive"
version = "0.4.2" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"lock_api", "lock_api",
"parking_lot 0.11.2", "parking_lot",
] ]
[[package]] [[package]]
@ -793,7 +808,7 @@ dependencies = [
"futures-sink", "futures-sink",
"futures-util", "futures-util",
"http", "http",
"indexmap", "indexmap 1.9.3",
"slab", "slab",
"tokio", "tokio",
"tokio-util", "tokio-util",
@ -812,7 +827,7 @@ version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
dependencies = [ dependencies = [
"ahash 0.8.6", "ahash",
"allocator-api2", "allocator-api2",
] ]
@ -864,6 +879,15 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "home"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
dependencies = [
"windows-sys",
]
[[package]] [[package]]
name = "html5ever" name = "html5ever"
version = "0.26.0" version = "0.26.0"
@ -1001,6 +1025,16 @@ dependencies = [
"hashbrown 0.12.3", "hashbrown 0.12.3",
] ]
[[package]]
name = "indexmap"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [
"equivalent",
"hashbrown 0.14.2",
]
[[package]] [[package]]
name = "infer" name = "infer"
version = "0.13.0" version = "0.13.0"
@ -1016,15 +1050,6 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "ipnet" name = "ipnet"
version = "2.9.0" version = "2.9.0"
@ -1069,6 +1094,9 @@ name = "lazy_static"
version = "1.4.0" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
dependencies = [
"spin 0.5.2",
]
[[package]] [[package]]
name = "lexical-core" name = "lexical-core"
@ -1095,6 +1123,17 @@ version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
[[package]]
name = "libsqlite3-sys"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326"
dependencies = [
"cc",
"pkg-config",
"vcpkg",
]
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.10" version = "0.4.10"
@ -1310,6 +1349,23 @@ dependencies = [
"rustc-serialize", "rustc-serialize",
] ]
[[package]]
name = "num-bigint-dig"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
dependencies = [
"byteorder",
"lazy_static",
"libm",
"num-integer",
"num-iter",
"num-traits 0.2.17",
"rand 0.8.5",
"smallvec",
"zeroize",
]
[[package]] [[package]]
name = "num-complex" name = "num-complex"
version = "0.1.43" version = "0.1.43"
@ -1369,6 +1425,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"libm",
] ]
[[package]] [[package]]
@ -1446,17 +1503,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "parking_lot"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
dependencies = [
"instant",
"lock_api",
"parking_lot_core 0.8.6",
]
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.1" version = "0.12.1"
@ -1464,21 +1510,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [ dependencies = [
"lock_api", "lock_api",
"parking_lot_core 0.9.9", "parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
dependencies = [
"cfg-if",
"instant",
"libc",
"redox_syscall 0.2.16",
"smallvec",
"winapi",
] ]
[[package]] [[package]]
@ -1489,7 +1521,7 @@ checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"redox_syscall 0.4.1", "redox_syscall",
"smallvec", "smallvec",
"windows-targets", "windows-targets",
] ]
@ -1523,6 +1555,15 @@ dependencies = [
"sha2", "sha2",
] ]
[[package]]
name = "pem-rfc7468"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
dependencies = [
"base64ct",
]
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.3.0" version = "2.3.0"
@ -1633,6 +1674,27 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkcs1"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
dependencies = [
"der",
"pkcs8",
"spki",
]
[[package]]
name = "pkcs8"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
dependencies = [
"der",
"spki",
]
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.27" version = "0.3.27"
@ -1805,15 +1867,6 @@ dependencies = [
"rand_core 0.3.1", "rand_core 0.3.1",
] ]
[[package]]
name = "redox_syscall"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags 1.3.2",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.4.1" version = "0.4.1"
@ -1823,17 +1876,6 @@ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
] ]
[[package]]
name = "redox_users"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [
"getrandom 0.2.10",
"redox_syscall 0.2.16",
"thiserror",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.10.2" version = "1.10.2"
@ -1869,7 +1911,7 @@ version = "0.11.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b"
dependencies = [ dependencies = [
"base64 0.21.5", "base64",
"bytes", "bytes",
"encoding_rs", "encoding_rs",
"futures-core", "futures-core",
@ -1903,6 +1945,26 @@ dependencies = [
"winreg", "winreg",
] ]
[[package]]
name = "rsa"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86ef35bf3e7fe15a53c4ab08a998e42271eab13eb0db224126bc7bc4c4bad96d"
dependencies = [
"const-oid",
"digest",
"num-bigint-dig",
"num-integer",
"num-traits 0.2.17",
"pkcs1",
"pkcs8",
"rand_core 0.6.4",
"signature",
"spki",
"subtle",
"zeroize",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.23" version = "0.1.23"
@ -1973,7 +2035,7 @@ version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59e25654b5e9fd557a67dbaab5a5d36b8c448d0561beb4c041b6dbb902eddfa6" checksum = "59e25654b5e9fd557a67dbaab5a5d36b8c448d0561beb4c041b6dbb902eddfa6"
dependencies = [ dependencies = [
"ahash 0.8.6", "ahash",
"cssparser", "cssparser",
"ego-tree", "ego-tree",
"getopts", "getopts",
@ -2130,6 +2192,16 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "signature"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
"digest",
"rand_core 0.6.4",
]
[[package]] [[package]]
name = "siphasher" name = "siphasher"
version = "0.3.11" version = "0.3.11"
@ -2185,6 +2257,31 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[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.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "spki"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a"
dependencies = [
"base64ct",
"der",
]
[[package]] [[package]]
name = "sqlformat" name = "sqlformat"
version = "0.2.2" version = "0.2.2"
@ -2198,97 +2295,204 @@ dependencies = [
[[package]] [[package]]
name = "sqlx" name = "sqlx"
version = "0.6.3" version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" checksum = "0e50c216e3624ec8e7ecd14c6a6a6370aad6ee5d8cfc3ab30b5162eeeef2ed33"
dependencies = [ dependencies = [
"sqlx-core", "sqlx-core",
"sqlx-macros", "sqlx-macros",
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
] ]
[[package]] [[package]]
name = "sqlx-core" name = "sqlx-core"
version = "0.6.3" version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" checksum = "8d6753e460c998bbd4cd8c6f0ed9a64346fcca0723d6e75e52fdc351c5d2169d"
dependencies = [ dependencies = [
"ahash 0.7.7", "ahash",
"atoi", "atoi",
"base64 0.13.1",
"bitflags 1.3.2",
"byteorder", "byteorder",
"bytes", "bytes",
"chrono", "chrono",
"crc", "crc",
"crossbeam-queue", "crossbeam-queue",
"dirs",
"dotenvy", "dotenvy",
"either", "either",
"event-listener", "event-listener",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-intrusive", "futures-intrusive",
"futures-io",
"futures-util", "futures-util",
"hashlink", "hashlink",
"hex", "hex",
"indexmap 2.1.0",
"log",
"memchr",
"native-tls",
"once_cell",
"paste",
"percent-encoding",
"serde",
"serde_json",
"sha2",
"smallvec",
"sqlformat",
"thiserror",
"tokio",
"tokio-stream",
"tracing",
"url",
]
[[package]]
name = "sqlx-macros"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a793bb3ba331ec8359c1853bd39eed32cdd7baaf22c35ccf5c92a7e8d1189ec"
dependencies = [
"proc-macro2",
"quote",
"sqlx-core",
"sqlx-macros-core",
"syn 1.0.109",
]
[[package]]
name = "sqlx-macros-core"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a4ee1e104e00dedb6aa5ffdd1343107b0a4702e862a84320ee7cc74782d96fc"
dependencies = [
"dotenvy",
"either",
"heck",
"hex",
"once_cell",
"proc-macro2",
"quote",
"serde",
"serde_json",
"sha2",
"sqlx-core",
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
"syn 1.0.109",
"tempfile",
"tokio",
"url",
]
[[package]]
name = "sqlx-mysql"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db"
dependencies = [
"atoi",
"base64",
"bitflags 2.4.1",
"byteorder",
"bytes",
"chrono",
"crc",
"digest",
"dotenvy",
"either",
"futures-channel",
"futures-core",
"futures-io",
"futures-util",
"generic-array",
"hex",
"hkdf", "hkdf",
"hmac", "hmac",
"indexmap",
"itoa", "itoa",
"libc",
"log", "log",
"md-5", "md-5",
"memchr", "memchr",
"once_cell", "once_cell",
"paste",
"percent-encoding", "percent-encoding",
"rand 0.8.5", "rand 0.8.5",
"rsa",
"serde",
"sha1",
"sha2",
"smallvec",
"sqlx-core",
"stringprep",
"thiserror",
"tracing",
"whoami",
]
[[package]]
name = "sqlx-postgres"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624"
dependencies = [
"atoi",
"base64",
"bitflags 2.4.1",
"byteorder",
"chrono",
"crc",
"dotenvy",
"etcetera",
"futures-channel",
"futures-core",
"futures-io",
"futures-util",
"hex",
"hkdf",
"hmac",
"home",
"itoa",
"log",
"md-5",
"memchr",
"once_cell",
"rand 0.8.5",
"serde", "serde",
"serde_json", "serde_json",
"sha1", "sha1",
"sha2", "sha2",
"smallvec", "smallvec",
"sqlformat", "sqlx-core",
"sqlx-rt",
"stringprep", "stringprep",
"thiserror", "thiserror",
"tokio-stream", "tracing",
"url",
"whoami", "whoami",
] ]
[[package]] [[package]]
name = "sqlx-macros" name = "sqlx-sqlite"
version = "0.6.3" version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" checksum = "d59dc83cf45d89c555a577694534fcd1b55c545a816c816ce51f20bbe56a4f3f"
dependencies = [ dependencies = [
"dotenvy", "atoi",
"either", "chrono",
"heck", "flume",
"once_cell", "futures-channel",
"proc-macro2", "futures-core",
"quote", "futures-executor",
"serde_json", "futures-intrusive",
"sha2", "futures-util",
"libsqlite3-sys",
"log",
"percent-encoding",
"serde",
"sqlx-core", "sqlx-core",
"sqlx-rt", "tracing",
"syn 1.0.109",
"url", "url",
] ]
[[package]]
name = "sqlx-rt"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024"
dependencies = [
"native-tls",
"once_cell",
"tokio",
"tokio-native-tls",
]
[[package]] [[package]]
name = "stable_deref_trait" name = "stable_deref_trait"
version = "1.2.0" version = "1.2.0"
@ -2309,7 +2513,7 @@ checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b"
dependencies = [ dependencies = [
"new_debug_unreachable", "new_debug_unreachable",
"once_cell", "once_cell",
"parking_lot 0.12.1", "parking_lot",
"phf_shared 0.10.0", "phf_shared 0.10.0",
"precomputed-hash", "precomputed-hash",
"serde", "serde",
@ -2401,7 +2605,7 @@ checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand",
"redox_syscall 0.4.1", "redox_syscall",
"rustix", "rustix",
"windows-sys", "windows-sys",
] ]
@ -2493,16 +2697,16 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.33.0" version = "1.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"bytes", "bytes",
"libc", "libc",
"mio", "mio",
"num_cpus", "num_cpus",
"parking_lot 0.12.1", "parking_lot",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry", "signal-hook-registry",
"socket2 0.5.5", "socket2 0.5.5",
@ -2512,9 +2716,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-macros" name = "tokio-macros"
version = "2.1.0" version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2569,6 +2773,7 @@ version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [ dependencies = [
"log",
"pin-project-lite", "pin-project-lite",
"tracing-attributes", "tracing-attributes",
"tracing-core", "tracing-core",
@ -2866,10 +3071,6 @@ name = "whoami"
version = "1.4.1" version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50"
dependencies = [
"wasm-bindgen",
"web-sys",
]
[[package]] [[package]]
name = "widestring" name = "widestring"
@ -3019,6 +3220,12 @@ dependencies = [
"syn 2.0.38", "syn 2.0.38",
] ]
[[package]]
name = "zeroize"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12a3946ecfc929b583800f4629b6c25b88ac6e92a40ea5670f77112a85d40a8b"
[[package]] [[package]]
name = "zip" name = "zip"
version = "0.6.6" version = "0.6.6"

View File

@ -21,10 +21,10 @@ scraper = "0.16"
seahash = "4.1" seahash = "4.1"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
sqlx = { version = "0.6", features = ["runtime-tokio-native-tls", "postgres", "migrate", "chrono", "json"] } sqlx = { version = "0.7", features = ["runtime-tokio-native-tls", "postgres", "migrate", "chrono", "json"] }
skyrim-cell-dump = "0.4" skyrim-cell-dump = "0.4"
tempfile = "3.5" tempfile = "3.5"
tokio = { version = "1.27", features = ["full"] } tokio = { version = "1.34", features = ["full"] }
tokio-util = { version = "0.7", features = ["compat"] } tokio-util = { version = "0.7", features = ["compat"] }
tracing = "0.1" tracing = "0.1"
tracing-appender = "0.2" tracing-appender = "0.2"

View File

@ -0,0 +1,47 @@
use crate::models::cell::{self, CellFileEditCount};
use anyhow::Result;
use chrono::{Duration, NaiveDateTime};
use std::collections::HashMap;
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
use tracing::{debug, info};
pub async fn dump_cell_edit_counts_over_time(
pool: &sqlx::Pool<sqlx::Postgres>,
start_date: NaiveDateTime,
end_date: NaiveDateTime,
path: &str,
) -> Result<()> {
let mut current_date = start_date;
while current_date <= end_date {
let next_date = current_date + Duration::weeks(1);
let mut cell_file_edit_counts = HashMap::new();
let counts =
cell::count_file_edits_in_time_range(pool, "Skyrim.esm", 1, current_date, next_date)
.await?;
for x in -77..75 {
for y in -50..44 {
let count: Option<&CellFileEditCount> = counts.iter().find(|c| c.x.unwrap() == x && c.y.unwrap() == y);
let count = count.map(|c| c.count).unwrap_or(Some(0)).unwrap();
debug!(x = x, y = y, count = count, "read cell edit count");
cell_file_edit_counts.insert(format!("{},{}", x, y), count);
}
}
let file_name = format!(
"{}/cell_edits_{}.json",
path,
current_date.format("%Y-%m-%d")
);
info!(
"writing {} cell edit counts to {}",
cell_file_edit_counts.values().sum::<i64>(),
file_name
);
let mut file = File::create(&file_name).await?;
file.write_all(serde_json::to_string(&cell_file_edit_counts)?.as_bytes()).await?;
current_date = next_date;
}
Ok(())
}

View File

@ -2,6 +2,7 @@ pub mod backfills;
pub mod download_tiles; pub mod download_tiles;
pub mod dump_cell_data; pub mod dump_cell_data;
pub mod dump_cell_edit_counts; pub mod dump_cell_edit_counts;
pub mod dump_cell_edit_counts_over_time;
pub mod dump_file_data; pub mod dump_file_data;
pub mod dump_games; pub mod dump_games;
pub mod dump_mod_cell_counts; pub mod dump_mod_cell_counts;
@ -13,6 +14,7 @@ pub mod update;
pub use download_tiles::download_tiles; pub use download_tiles::download_tiles;
pub use dump_cell_data::dump_cell_data; pub use dump_cell_data::dump_cell_data;
pub use dump_cell_edit_counts::dump_cell_edit_counts; pub use dump_cell_edit_counts::dump_cell_edit_counts;
pub use dump_cell_edit_counts_over_time::dump_cell_edit_counts_over_time;
pub use dump_file_data::dump_file_data; pub use dump_file_data::dump_file_data;
pub use dump_games::dump_games; pub use dump_games::dump_games;
pub use dump_mod_cell_counts::dump_mod_cell_counts; pub use dump_mod_cell_counts::dump_mod_cell_counts;

View File

@ -1,6 +1,6 @@
use anyhow::Result; use anyhow::Result;
use argh::FromArgs; use argh::FromArgs;
use chrono::NaiveDateTime; use chrono::{NaiveDateTime, NaiveDate, Utc};
use dotenv::dotenv; use dotenv::dotenv;
use sqlx::postgres::PgPoolOptions; use sqlx::postgres::PgPoolOptions;
use std::env; use std::env;
@ -15,8 +15,8 @@ mod plugin_processor;
use commands::{ use commands::{
backfills::backfill_is_base_game, backfills::backfill_is_translation, backfills::backfill_is_base_game, backfills::backfill_is_translation,
backfills::deduplicate_interior_cells, download_tiles, dump_cell_data, dump_cell_edit_counts, backfills::deduplicate_interior_cells, download_tiles, dump_cell_data, dump_cell_edit_counts,
dump_file_data, dump_games, dump_mod_cell_counts, dump_mod_data, dump_mod_search_index, dump_cell_edit_counts_over_time, dump_file_data, dump_games, dump_mod_cell_counts,
dump_plugin_data, update, dump_mod_data, dump_mod_search_index, dump_plugin_data, update,
}; };
#[derive(FromArgs)] #[derive(FromArgs)]
@ -42,6 +42,10 @@ struct Args {
#[argh(option, short = 'e')] #[argh(option, short = 'e')]
dump_edits: Option<String>, dump_edits: Option<String>,
/// file to output the cell mod edit counts over time as json
#[argh(option, short = 'E')]
dump_edits_over_time: Option<String>,
/// folder to output all cell data as json files /// folder to output all cell data as json files
#[argh(option, short = 'c')] #[argh(option, short = 'c')]
cell_data: Option<String>, cell_data: Option<String>,
@ -107,6 +111,15 @@ pub async fn main() -> Result<()> {
if let Some(path) = args.dump_edits { if let Some(path) = args.dump_edits {
return dump_cell_edit_counts(&pool, &path).await; return dump_cell_edit_counts(&pool, &path).await;
} }
if let Some(path) = args.dump_edits_over_time {
return dump_cell_edit_counts_over_time(
&pool,
NaiveDate::from_ymd_opt(2011, 11, 11).unwrap().and_hms_opt(0, 0, 0).unwrap(),
Utc::now().naive_utc(),
&path,
)
.await;
}
if let Some(dir) = args.cell_data { if let Some(dir) = args.cell_data {
return dump_cell_data(&pool, &dir).await; return dump_cell_data(&pool, &dir).await;
} }

View File

@ -150,6 +150,43 @@ pub async fn count_mod_edits(
.context("Failed to count mod edits on cell") .context("Failed to count mod edits on cell")
} }
#[derive(Debug, Serialize, Deserialize, FromRow)]
pub struct CellFileEditCount {
pub x: Option<i32>,
pub y: Option<i32>,
pub count: Option<i64>,
}
#[instrument(level = "debug", skip(pool))]
pub async fn count_file_edits_in_time_range(
pool: &sqlx::Pool<sqlx::Postgres>,
master: &str,
world_id: i32,
start_date: NaiveDateTime,
end_date: NaiveDateTime,
) -> Result<Vec<CellFileEditCount>> {
sqlx::query_as!(
CellFileEditCount,
"SELECT cells.x, cells.y, COUNT(DISTINCT files.id)
FROM cells
JOIN plugin_cells on cells.id = cell_id
JOIN plugins ON plugins.id = plugin_id
JOIN files ON files.id = plugins.file_id
WHERE master = $1 AND world_id = $2
AND cells.x IS NOT NULL and cells.y IS NOT NULL
AND files.uploaded_at BETWEEN $3 AND $4
GROUP BY cells.x, cells.y
",
master,
world_id,
start_date,
end_date,
)
.fetch_all(pool)
.await
.context("Failed to count file-based mod edits on cell")
}
/// Returns cell properties plus a list of mods that edit the cell /// Returns cell properties plus a list of mods that edit the cell
#[instrument(level = "debug", skip(pool))] #[instrument(level = "debug", skip(pool))]
pub async fn get_cell_data( pub async fn get_cell_data(