Browse Source

init

master
Milan 2 years ago
commit
8ec049541a
  1. 669
      Cargo.lock
  2. 14
      Cargo.toml
  3. 53
      src/index.html
  4. 43
      src/index.html.hbs
  5. 194
      src/main.rs

669
Cargo.lock

@ -0,0 +1,669 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "anymap"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344"
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[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 = "byte-tools"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
[[package]]
name = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "chashmap"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff41a3c2c1e39921b9003de14bf0439c7b63a9039637c291e1a64925d8ddfa45"
dependencies = [
"owning_ref",
"parking_lot",
]
[[package]]
name = "crossbeam-channel"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061"
dependencies = [
"crossbeam-utils",
"maybe-uninit",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
"autocfg",
"cfg-if",
"lazy_static",
]
[[package]]
name = "digest"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
dependencies = [
"generic-array",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
name = "filetime"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ff6d4dab0aa0c8e6346d46052e93b13a16cf847b54ed357087c35011048cc7d"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"winapi 0.3.8",
]
[[package]]
name = "fsevent"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1616e68919f49d311720c3cf316e0a3522d8f2bd08f8da35f6b8a0fa12f9234b"
dependencies = [
"bitflags",
"fsevent-sys",
]
[[package]]
name = "fsevent-sys"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a41f1722e9bf862f62429d192f37d0c82c589aa18783aa06f0c4e5c3c90649fb"
dependencies = [
"libc",
]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
dependencies = [
"bitflags",
"fuchsia-zircon-sys",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
[[package]]
name = "generic-array"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
dependencies = [
"typenum",
]
[[package]]
name = "handlebars"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba758d094d31274eb49d15da6f326b96bf3185239a6359bf684f3d5321148900"
dependencies = [
"log",
"pest",
"pest_derive",
"quick-error",
"serde",
"serde_json",
]
[[package]]
name = "inotify"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc39ee997811267bf8aa0b10e1674c5bea6caacc1957eede5ea45251fe33c6d5"
dependencies = [
"bitflags",
"inotify-sys",
"libc",
]
[[package]]
name = "inotify-sys"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0"
dependencies = [
"libc",
]
[[package]]
name = "iovec"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
dependencies = [
"libc",
]
[[package]]
name = "itoa"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
dependencies = [
"winapi 0.2.8",
"winapi-build",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
[[package]]
name = "libc"
version = "0.2.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
[[package]]
name = "log"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
dependencies = [
"cfg-if",
]
[[package]]
name = "maplit"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
name = "maybe-uninit"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
[[package]]
name = "mio"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
dependencies = [
"cfg-if",
"fuchsia-zircon",
"fuchsia-zircon-sys",
"iovec",
"kernel32-sys",
"libc",
"log",
"miow",
"net2",
"slab",
"winapi 0.2.8",
]
[[package]]
name = "mio-extras"
version = "2.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
dependencies = [
"lazycell",
"log",
"mio",
"slab",
]
[[package]]
name = "miow"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
dependencies = [
"kernel32-sys",
"net2",
"winapi 0.2.8",
"ws2_32-sys",
]
[[package]]
name = "net2"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
dependencies = [
"cfg-if",
"libc",
"winapi 0.3.8",
]
[[package]]
name = "notify"
version = "5.0.0-pre.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b00c0b65188bffb5598c302e19b062feb94adef02c31f15622a163c95d673c3"
dependencies = [
"anymap",
"bitflags",
"chashmap",
"crossbeam-channel",
"filetime",
"fsevent",
"fsevent-sys",
"inotify",
"libc",
"mio",
"mio-extras",
"walkdir",
"winapi 0.3.8",
]
[[package]]
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
[[package]]
name = "owning_ref"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
dependencies = [
"stable_deref_trait",
]
[[package]]
name = "parking_lot"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e"
dependencies = [
"owning_ref",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa"
dependencies = [
"libc",
"rand",
"smallvec",
"winapi 0.3.8",
]
[[package]]
name = "pest"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
dependencies = [
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27e5277315f6b4f27e0e6744feb5d5ba1891e7164871033d3c8344c6783b349a"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pest_meta"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
dependencies = [
"maplit",
"pest",
"sha-1",
]
[[package]]
name = "proc-macro2"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quote"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
dependencies = [
"fuchsia-cprng",
"libc",
"rand_core 0.3.1",
"rdrand",
"winapi 0.3.8",
]
[[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 = "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.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
[[package]]
name = "rs-index"
version = "0.1.0"
dependencies = [
"crossbeam-channel",
"handlebars",
"notify",
"serde",
"serde_json",
]
[[package]]
name = "ryu"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "serde"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha-1"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
dependencies = [
"block-buffer",
"digest",
"fake-simd",
"opaque-debug",
]
[[package]]
name = "slab"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
[[package]]
name = "smallvec"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
dependencies = [
"maybe-uninit",
]
[[package]]
name = "stable_deref_trait"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
[[package]]
name = "syn"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "typenum"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
[[package]]
name = "ucd-trie"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f00ed7be0c1ff1e24f46c3d2af4859f7e863672ba3a6e92e7cff702bf9f06c2"
[[package]]
name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]]
name = "walkdir"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
dependencies = [
"same-file",
"winapi 0.3.8",
"winapi-util",
]
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
[[package]]
name = "winapi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
[[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.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80"
dependencies = [
"winapi 0.3.8",
]
[[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 = "ws2_32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
dependencies = [
"winapi 0.2.8",
"winapi-build",
]

14
Cargo.toml

@ -0,0 +1,14 @@
[package]
name = "rs-index"
version = "0.1.0"
authors = ["Milan Pässler <me@pbb.lc>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
crossbeam-channel = "0.4"
notify = "5.0.0-pre.2"
handlebars = "3.0"
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }

53
src/index.html

@ -0,0 +1,53 @@
<style>
html {
background: url('/public/.wallpaper.webp'), #332244;
background-size: cover;
background-position: center center;
background-attachment: fixed;
max-height: 100vh;
}
body {
font-family: sans-serif;
background-color: rgba(0, 0, 0, .7);
color: #ccc;
margin: 0 auto;
padding: 1em;
max-width: 1000px;
}
a {
color: #eee;
}
.size {
width: 4em;
display: inline-block;
}
</style>
<h2>foo</h2>
<p>
<span class="size"></span>
<a href="..">../</a>
</p>
<p>
<span class="size">12.00 KiB</span>
<a href=".">./</a>
</p>
<p>
<span class="size">8.00 KiB</span>
<a href="/home/pbb/proj/rs-index/src/main.rs">/home/pbb/proj/rs-index/src/main.rs</a>
</p>
<p>
<span class="size">4.00 KiB</span>
<a href="/home/pbb/proj/rs-index/src/index.html.hbs">/home/pbb/proj/rs-index/src/index.html.hbs</a>
</p>
<p>
<span class="size">0 B</span>
<a href="/home/pbb/proj/rs-index/src/index.html">/home/pbb/proj/rs-index/src/index.html</a>
</p>

43
src/index.html.hbs

@ -0,0 +1,43 @@
<style>
html {
background: url('/public/.wallpaper.webp'), #332244;
background-size: cover;
background-position: center center;
background-attachment: fixed;
max-height: 100vh;
}
body {
font-family: sans-serif;
background-color: rgba(0, 0, 0, .7);
color: #ccc;
margin: 0 auto;
padding: 1em;
max-width: 1000px;
}
a {
color: #eee;
}
.size {
width: 4.5em;
display: inline-block;
}
</style>
<h2>{{ name }}</h2>
<p>
<span class="size"></span>
<a href="..">../</a>
</p>
<p>
<span class="size">{{ size }}</span>
<a href=".">./</a>
</p>
{{#each entries}}
<p>
<span class="size">{{ size }}</span>
<a href="{{ name }}">{{ name }}</a>
</p>
{{/each}}

194
src/main.rs

@ -0,0 +1,194 @@
use notify::{RecursiveMode, Result, Watcher, RecommendedWatcher, Event, EventKind};
use std::time::Duration;
use std::{thread, env};
use std::path::{PathBuf, Path};
use std::sync::{Arc, RwLock};
use std::fs;
use std::io::Write;
use handlebars::Handlebars;
use serde_json::json;
use std::os::linux::fs::MetadataExt;
use serde::Serialize;
const DIRECTORY_INDEX_TEMPLATE : &'static str = include_str!("index.html.hbs");
#[derive(Serialize)]
struct TemplateData {
name: String,
size: String,
entries: Vec<TemplateEntry>
}
#[derive(Serialize)]
struct TemplateEntry {
name: String,
size: String,
}
fn try_is_symlink( path : &Path ) -> bool {
let metadata = path.symlink_metadata();
metadata.is_ok() && metadata.unwrap().file_type().is_symlink()
}
fn file_name_from_path( path : &Path ) -> String {
let mut abspath = std::env::current_dir().unwrap();
abspath.push( path );
// don't resolve links
if !try_is_symlink( path ) {
abspath = abspath.canonicalize().unwrap_or( abspath );
}
abspath.file_name().unwrap_or( std::ffi::OsStr::new( "/" ) ) // '/' has no filename
.to_str().unwrap_or( "[invalid name]" ).to_string()
}
fn try_read_dir( path : &Path ) -> Option<fs::ReadDir> {
if try_is_symlink( path ) { return None } // don't follow symlinks
match path.read_dir() {
Ok(dir_list) => Some(dir_list),
Err(err) => {
print_io_error(path, err);
None
},
}
}
fn try_bytes_from_path( path : &Path, usage_flag : bool ) -> u64 {
match path.symlink_metadata() {
Ok(metadata) => if usage_flag { metadata.st_blocks()*512 } else { metadata.st_size() },
Err(err) => {
print_io_error(path, err);
0
},
}
}
fn print_io_error( path: &Path, err: std::io::Error ) {
eprintln!( "Couldn't read {} ({:?})", file_name_from_path( path ), err.kind() )
}
fn print_notify_error( path: &Path, err: notify::Error ) {
eprintln!( "Couldn't read {} ({:?})", file_name_from_path( path ), err.kind )
}
fn path_from_dentry( entry : std::result::Result<fs::DirEntry, std::io::Error> ) -> Option<std::path::PathBuf> {
match entry {
Ok(entry) => {
Some( entry.path() )
},
Err(err) => {
eprintln!( "Couldn't read entry ({:?})", err.kind() );
None
},
}
}
fn fmt_size_str( bytes : u64, flag : bool ) -> String {
let b = bytes as f32;
if bytes < 1024 || flag { format!( "{:.0} B" , bytes ) }
else if bytes < 1024*10 { format!( "{:.2} KiB", b/1024.0 ) }
else if bytes < 1024u64.pow(2) { format!( "{:.0} KiB", b/1024.0 ) }
else if bytes < 1024u64.pow(2) * 10 { format!( "{:.2} MiB", b/(1024u32.pow(2) as f32)) }
else if bytes < 1024u64.pow(3) { format!( "{:.0} MiB", b/(1024u32.pow(2) as f32)) }
else if bytes < 1024u64.pow(3) * 10 { format!( "{:.2} GiB", b/(1024u32.pow(3) as f32)) }
else if bytes < 1024u64.pow(4) { format!( "{:.0} GiB", b/(1024u32.pow(3) as f32)) }
else if bytes < 1024u64.pow(4) * 10 { format!( "{:.2} GiB", b/(1024u32.pow(3) as f32)) }
else { format!( "{:.2} TiB", b/(1024u64.pow(4) as f32)) }
}
fn get_bytes( path: &Path, usage_flag : bool ) -> u64 {
if path.is_dir() {
let mut bytes : u64 = try_bytes_from_path( path, usage_flag );
if let Some(dir_list) = try_read_dir( path ) {
for entry in dir_list {
if let Some(path) = path_from_dentry(entry) {
bytes += get_bytes( &path, usage_flag );
}
}
}
bytes
} else {
try_bytes_from_path( path, usage_flag )
}
}
fn main() -> Result<()> {
let dirty_dirs = Arc::new(RwLock::new(vec![]));
let root = env::current_dir()?;
let mut watcher: RecommendedWatcher;
{
let dirty_dirs = dirty_dirs.clone();
let root = root.clone();
watcher = Watcher::new_immediate(move |res: Result<Event>| {
let mark_as_dirty = |paths: Vec<PathBuf>| -> Result<()> {
for mut path in paths {
if path.is_file() {
path.pop();
}
loop {
if !dirty_dirs.read()?.contains(&path.clone()) {
dirty_dirs.write()?.push(path.clone());
}
if path.eq(&root) {
break;
}
if !path.pop() {
break;
}
}
}
Ok(())
};
match res {
Ok(event) => {
// println!("event: {:?}", event);
match event.kind {
EventKind::Create(_) => mark_as_dirty(event.paths),
EventKind::Modify(_) => mark_as_dirty(event.paths),
EventKind::Remove(_) => mark_as_dirty(event.paths),
_ => Ok(()),
}.unwrap();
},
Err(e) => println!("watch error: {:?}", e),
};
})?;
}
watcher.watch(root, RecursiveMode::Recursive)?;
let mut reg = Handlebars::new();
reg.register_template_string("directory_index", DIRECTORY_INDEX_TEMPLATE).unwrap();
let update_index = |dir: PathBuf| -> Result<()> {
let mut file = fs::File::create(dir.as_path().join("index.html"))?;
let input = TemplateData {
name: "foo".to_string(),
size: fmt_size_str(get_bytes(dir.as_path(), true), false),
entries: try_read_dir(dir.as_path()).unwrap().map(|entry| -> Result<TemplateEntry> {
let entry = entry.unwrap();
Ok(TemplateEntry {
name: entry.path().strip_prefix(&dir).unwrap().to_str().unwrap().to_string(),
size: fmt_size_str(get_bytes(entry.path().as_path(), true), false),
})
}).filter(|r| r.is_ok()).map(|r| r.unwrap()).collect()
};
let text = reg.render("directory_index", &json!(input)).unwrap();
file.write_all(text.as_bytes())?;
Ok(())
};
loop {
thread::sleep(Duration::from_millis(100));
if !dirty_dirs.read()?.is_empty() {
// println!("should update: {:?}", dirty_dirs);
for dir in dirty_dirs.write()?.iter() {
update_index(dir.to_path_buf())?;
}
dirty_dirs.write()?.clear();
}
}
}
Loading…
Cancel
Save