Add cloud storage, fix upload and move to trunk
@ -82,9 +82,9 @@ fabric.properties
|
||||
|
||||
/tmp/
|
||||
|
||||
/web/target/
|
||||
/web/tmp/
|
||||
/web/build/
|
||||
crates/web/target/
|
||||
crates/web/tmp/
|
||||
crates/web/build/
|
||||
|
||||
/bitque-server/target/
|
||||
/bitque-server/tmp/
|
||||
crates/bitque-server/target/
|
||||
crates/bitque-server/tmp/
|
||||
|
2
.env
@ -1,5 +1,5 @@
|
||||
DEBUG=true
|
||||
RUST_LOG=debug
|
||||
RUST_LOG=info
|
||||
JIRS_CLIENT_PORT=80
|
||||
JIRS_CLIENT_BIND=bitque.lvh.me
|
||||
DATABASE_URL=postgres://postgres@localhost:5432/bitque
|
||||
|
35
.gitignore
vendored
@ -1,27 +1,12 @@
|
||||
/target
|
||||
|
||||
mail.toml
|
||||
mail.test.toml
|
||||
web.toml
|
||||
web.test.toml
|
||||
db.toml
|
||||
db.test.toml
|
||||
fs.toml
|
||||
fs.test.toml
|
||||
highlight.toml
|
||||
highlight.test.toml
|
||||
|
||||
pkg
|
||||
bitque-client/pkg
|
||||
bitque-client/tmp
|
||||
bitque-client/build
|
||||
/crates/bitque-client/pkg
|
||||
/crates/bitque-client/tmp
|
||||
/crates/bitque-client/build
|
||||
/crates/bitque-server/target
|
||||
/crates/bitque-cli/target
|
||||
/crates/bitque-bat/bat
|
||||
/crates/highlight/bitque-highlight/build
|
||||
/crates/bitque-client/src/location.rs
|
||||
/uploads
|
||||
/config
|
||||
tmp
|
||||
bitque-server/target
|
||||
bitque-cli/target
|
||||
bitque-bat/bat
|
||||
|
||||
highlight/bitque-highlight/build
|
||||
uploads
|
||||
config
|
||||
shared/bitque-config/target
|
||||
bitque-client/src/location.rs
|
||||
|
417
Cargo.lock
generated
@ -234,7 +234,7 @@ dependencies = [
|
||||
"ahash 0.7.6",
|
||||
"bytes",
|
||||
"bytestring",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"cookie",
|
||||
"derive_more",
|
||||
"encoding_rs",
|
||||
@ -321,7 +321,7 @@ version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check 0.9.4",
|
||||
@ -400,6 +400,12 @@ dependencies = [
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anymap2"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c"
|
||||
|
||||
[[package]]
|
||||
name = "ascii_utils"
|
||||
version = "0.9.3"
|
||||
@ -601,6 +607,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"actix",
|
||||
"chrono",
|
||||
"derive_enum_primitive",
|
||||
"diesel 2.0.3",
|
||||
"diesel-derive-enum 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"diesel-derive-more",
|
||||
@ -611,6 +618,35 @@ dependencies = [
|
||||
"uuid 1.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitque_client"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bitque-data",
|
||||
"chrono",
|
||||
"console_error_panic_hook",
|
||||
"derive_enum_iter",
|
||||
"derive_enum_primitive",
|
||||
"dotenv",
|
||||
"futures",
|
||||
"js-sys",
|
||||
"seed",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tracing-subscriber-wasm",
|
||||
"uuid 1.3.0",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-bindgen-test",
|
||||
"wasm-sockets",
|
||||
"web-sys",
|
||||
"wee_alloc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitquec"
|
||||
version = "0.1.0"
|
||||
@ -693,6 +729,12 @@ dependencies = [
|
||||
"jobserver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@ -825,6 +867,16 @@ dependencies = [
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console_error_panic_hook"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
@ -873,7 +925,7 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -882,7 +934,7 @@ version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
@ -892,7 +944,7 @@ version = "0.8.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1042,6 +1094,15 @@ dependencies = [
|
||||
"uuid 1.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dbg"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4677188513e0e9d7adced5997cf9a1e7a3c996c994f90093325c5332c1a8b221"
|
||||
dependencies = [
|
||||
"version_check 0.1.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_db_execute"
|
||||
version = "0.1.0"
|
||||
@ -1250,6 +1311,12 @@ version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112"
|
||||
|
||||
[[package]]
|
||||
name = "enclose"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1056f553da426e9c025a662efa48b52e62e0a3a7648aa2d15aeaaf7f0d329357"
|
||||
|
||||
[[package]]
|
||||
name = "encoding"
|
||||
version = "0.2.33"
|
||||
@ -1320,7 +1387,7 @@ version = "0.8.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1552,9 +1619,179 @@ version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a4bef6b277b3ab073253d4bca60761240cf8d6998f4bd142211957b69a61b20"
|
||||
dependencies = [
|
||||
"gloo-console",
|
||||
"gloo-dialogs",
|
||||
"gloo-events",
|
||||
"gloo-file",
|
||||
"gloo-history",
|
||||
"gloo-net",
|
||||
"gloo-render",
|
||||
"gloo-storage",
|
||||
"gloo-timers",
|
||||
"gloo-utils",
|
||||
"gloo-worker",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo-console"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82b7ce3c05debe147233596904981848862b068862e9ec3e34be446077190d3f"
|
||||
dependencies = [
|
||||
"gloo-utils",
|
||||
"js-sys",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo-dialogs"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67062364ac72d27f08445a46cab428188e2e224ec9e37efdba48ae8c289002e6"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo-events"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68b107f8abed8105e4182de63845afcc7b69c098b7852a813ea7462a320992fc"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo-file"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8d5564e570a38b43d78bdc063374a0c3098c4f0d64005b12f9bbe87e869b6d7"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"gloo-events",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo-history"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd451019e0b7a2b8a7a7b23e74916601abf1135c54664e57ff71dcc26dfcdeb7"
|
||||
dependencies = [
|
||||
"gloo-events",
|
||||
"gloo-utils",
|
||||
"serde",
|
||||
"serde-wasm-bindgen",
|
||||
"serde_urlencoded",
|
||||
"thiserror",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo-net"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9902a044653b26b99f7e3693a42f171312d9be8b26b5697bd1e43ad1f8a35e10"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"gloo-utils",
|
||||
"js-sys",
|
||||
"pin-project",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo-render"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fd9306aef67cfd4449823aadcd14e3958e0800aa2183955a309112a84ec7764"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo-storage"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d6ab60bf5dbfd6f0ed1f7843da31b41010515c745735c970e821945ca91e480"
|
||||
dependencies = [
|
||||
"gloo-utils",
|
||||
"js-sys",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo-timers"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo-utils"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8e8fc851e9c7b9852508bc6e3f690f452f474417e8545ec9857b7f7377036b5"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo-worker"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13471584da78061a28306d1359dd0178d8d6fc1c7c80e5e35d27260346e0516a"
|
||||
dependencies = [
|
||||
"anymap2",
|
||||
"bincode",
|
||||
"gloo-console",
|
||||
"gloo-utils",
|
||||
"js-sys",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1781,7 +2018,7 @@ version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1981,7 +2218,7 @@ version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2040,6 +2277,12 @@ version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memory_units"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
@ -2211,7 +2454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
@ -2291,7 +2534,7 @@ version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"redox_syscall 0.2.16",
|
||||
"smallvec",
|
||||
@ -2316,6 +2559,26 @@ version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.54",
|
||||
"quote 1.0.26",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
@ -2734,7 +2997,7 @@ version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"ordered-multimap",
|
||||
]
|
||||
|
||||
@ -2748,7 +3011,7 @@ dependencies = [
|
||||
"aws-creds",
|
||||
"aws-region",
|
||||
"base64 0.13.1",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"hex",
|
||||
"hmac",
|
||||
"http",
|
||||
@ -2870,6 +3133,12 @@ dependencies = [
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
@ -2905,6 +3174,34 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "seed"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9352d75dd253803ce05722fe3acaafffc461d4faeaf0ebe0d8bf831059482e21"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"cookie",
|
||||
"dbg",
|
||||
"enclose",
|
||||
"futures",
|
||||
"getrandom",
|
||||
"gloo-file",
|
||||
"gloo-timers",
|
||||
"gloo-utils",
|
||||
"indexmap",
|
||||
"js-sys",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde-wasm-bindgen",
|
||||
"serde_json",
|
||||
"uuid 1.3.0",
|
||||
"version_check 0.9.4",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.17"
|
||||
@ -2920,6 +3217,17 @@ dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-wasm-bindgen"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-xml-rs"
|
||||
version = "0.5.1"
|
||||
@ -2990,7 +3298,7 @@ version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
@ -3007,7 +3315,7 @@ version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
@ -3110,6 +3418,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
@ -3224,7 +3538,7 @@ version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"fastrand",
|
||||
"redox_syscall 0.3.5",
|
||||
"rustix 0.37.5",
|
||||
@ -3300,7 +3614,7 @@ version = "1.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
@ -3468,7 +3782,7 @@ version = "0.1.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
@ -3526,6 +3840,17 @@ dependencies = [
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber-wasm"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79804e80980173c6c8e53d98508eb24a2dbc4ee17a3e8d2ca8e5bad6bf13a898"
|
||||
dependencies = [
|
||||
"gloo",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "triple_accel"
|
||||
version = "0.3.4"
|
||||
@ -3717,7 +4042,9 @@ version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
@ -3742,7 +4069,7 @@ version = "0.4.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
@ -3777,6 +4104,43 @@ version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db36fc0f9fb209e88fb3642590ae0205bb5a56216dabd963ba15879fe53a30b"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"js-sys",
|
||||
"scoped-tls",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-bindgen-test-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test-macro"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0734759ae6b3b1717d661fe4f016efcfb9828f5edb4520c18eaee05af3b43be9"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.54",
|
||||
"quote 1.0.26",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-sockets"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d14bbe65995269301ab677e5d69b3b69195447c01137ef44f72b10eecea55c77"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"log",
|
||||
"thiserror",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-streams"
|
||||
version = "0.2.3"
|
||||
@ -3854,6 +4218,19 @@ dependencies = [
|
||||
"uuid 1.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wee_alloc"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"libc",
|
||||
"memory_units",
|
||||
"spin",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wildmatch"
|
||||
version = "2.1.1"
|
||||
|
@ -26,7 +26,7 @@ members = [
|
||||
"./crates/cloud-storage-actor",
|
||||
"./crates/filesystem-actor",
|
||||
# Client
|
||||
# "./crates/web"
|
||||
"./crates/web"
|
||||
]
|
||||
exclude = [
|
||||
"crates/bitque-cli",
|
||||
|
@ -1,15 +0,0 @@
|
||||
FROM ubuntu:18.04
|
||||
|
||||
WORKDIR /app/
|
||||
|
||||
RUN apt-get update && apt-get install -y curl git openssl libpq-dev gcc openssl1.0 make cmake
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain nightly -y
|
||||
RUN . $HOME/.cargo/env && \
|
||||
rustup toolchain install nightly && rustup default nightly
|
||||
|
||||
RUN ls -al /app
|
||||
CMD . $HOME/.cargo/env && \
|
||||
cd ./bitque-server && \
|
||||
rm -Rf ./target/debug/bitque_server && \
|
||||
cargo build --bin bitque_server --release --no-default-features --features local-storage && \
|
||||
cp /app/target/release/bitque_server /app/build/
|
@ -13,12 +13,12 @@ name = "bitque_config"
|
||||
path = "./src/lib.rs"
|
||||
|
||||
[features]
|
||||
aws-s3 = ["rust-s3"]
|
||||
cloud-storage = ["rust-s3"]
|
||||
local-storage = []
|
||||
database = []
|
||||
hi = []
|
||||
mail = []
|
||||
web = ["aws-s3", "local-storage"]
|
||||
web = ["cloud-storage", "local-storage"]
|
||||
websocket = []
|
||||
default = ["local-storage", "database", "hi", "mail", "web", "websocket"]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[cfg(feature = "aws-s3")]
|
||||
pub mod amazon;
|
||||
#[cfg(feature = "cloud-storage")]
|
||||
pub mod cloud_storage;
|
||||
|
||||
#[cfg(feature = "database")]
|
||||
pub mod database;
|
||||
|
@ -14,13 +14,14 @@ path = "./src/lib.rs"
|
||||
|
||||
[features]
|
||||
backend = ["diesel", "actix", "diesel-derive-newtype"]
|
||||
frontend = []
|
||||
frontend = ['derive_enum_primitive']
|
||||
|
||||
[dependencies]
|
||||
actix = { version = "0.13.0", optional = true }
|
||||
chrono = { version = "*", features = ["serde"] }
|
||||
diesel = { version = "2.0.3", features = ["postgres", "numeric", "uuid", "r2d2"], optional = true }
|
||||
diesel-derive-enum = { version = "2.0.1", features = ["postgres"] }
|
||||
derive_enum_primitive = { workspace = true, optional = true }
|
||||
#diesel-derive-enum = { path = "../derive_enum_sql", features = ["postgres"] }
|
||||
diesel-derive-more = { version = "1.1.3" }
|
||||
diesel-derive-newtype = { version = "2.0.0-rc.0", optional = true }
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use chrono::NaiveDateTime;
|
||||
use derive_enum_primitive::*;
|
||||
#[cfg(feature = "backend")]
|
||||
use diesel::*;
|
||||
#[cfg(feature = "backend")]
|
||||
@ -55,10 +56,14 @@ pub type EndsAt = NaiveDateTime;
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Default,
|
||||
Deserialize,
|
||||
Display,
|
||||
EnumAsStr,
|
||||
EnumIter,
|
||||
EnumLabel,
|
||||
EnumString,
|
||||
EnumU32,
|
||||
Hash,
|
||||
IntoStaticStr,
|
||||
PartialEq,
|
||||
@ -66,27 +71,27 @@ pub type EndsAt = NaiveDateTime;
|
||||
Serialize,
|
||||
)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[cfg_attr(feature = "backend", PgType = "IssueTypeMapping")]
|
||||
pub enum IssueType {
|
||||
#[default]
|
||||
Task,
|
||||
Bug,
|
||||
Story,
|
||||
}
|
||||
|
||||
impl Default for IssueType {
|
||||
fn default() -> Self {
|
||||
IssueType::Task
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "backend", derive(DbEnum))]
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Default,
|
||||
Deserialize,
|
||||
Display,
|
||||
EnumAsStr,
|
||||
EnumIter,
|
||||
EnumLabel,
|
||||
EnumString,
|
||||
EnumU32,
|
||||
Hash,
|
||||
IntoStaticStr,
|
||||
PartialEq,
|
||||
@ -94,36 +99,38 @@ impl Default for IssueType {
|
||||
Serialize,
|
||||
)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[cfg_attr(feature = "backend", PgType = "IssuePriorityMapping")]
|
||||
pub enum IssuePriority {
|
||||
Highest,
|
||||
High,
|
||||
#[default]
|
||||
Medium,
|
||||
Low,
|
||||
Lowest,
|
||||
}
|
||||
|
||||
impl Default for IssuePriority {
|
||||
fn default() -> Self {
|
||||
IssuePriority::Medium
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "backend", derive(DbEnum))]
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Default,
|
||||
Deserialize,
|
||||
Display,
|
||||
EnumAsStr,
|
||||
EnumIter,
|
||||
EnumLabel,
|
||||
EnumString,
|
||||
EnumU32,
|
||||
Hash,
|
||||
IntoStaticStr,
|
||||
PartialEq,
|
||||
Serialize,
|
||||
)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[cfg_attr(feature = "backend", PgType = "UserRoleMapping")]
|
||||
pub enum UserRole {
|
||||
#[default]
|
||||
User,
|
||||
Manager,
|
||||
Owner,
|
||||
@ -144,22 +151,20 @@ impl PartialOrd for UserRole {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for UserRole {
|
||||
fn default() -> Self {
|
||||
UserRole::User
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "backend", derive(DbEnum))]
|
||||
#[cfg_attr(feature = "backend", PgType = "ProjectCategoryMapping")]
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Default,
|
||||
Deserialize,
|
||||
Display,
|
||||
EnumAsStr,
|
||||
EnumIter,
|
||||
EnumLabel,
|
||||
EnumString,
|
||||
EnumU32,
|
||||
Hash,
|
||||
IntoStaticStr,
|
||||
PartialEq,
|
||||
@ -167,28 +172,27 @@ impl Default for UserRole {
|
||||
Serialize,
|
||||
)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[cfg_attr(feature = "backend", PgType = "ProjectCategoryMapping")]
|
||||
pub enum ProjectCategory {
|
||||
#[default]
|
||||
Software,
|
||||
Marketing,
|
||||
Business,
|
||||
}
|
||||
|
||||
impl Default for ProjectCategory {
|
||||
fn default() -> Self {
|
||||
ProjectCategory::Software
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "backend", derive(DbEnum))]
|
||||
#[cfg_attr(feature = "backend", PgType = "InvitationStateMapping")]
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Default,
|
||||
Deserialize,
|
||||
Display,
|
||||
EnumAsStr,
|
||||
EnumIter,
|
||||
EnumString,
|
||||
EnumU32,
|
||||
Hash,
|
||||
IntoStaticStr,
|
||||
PartialEq,
|
||||
@ -196,28 +200,28 @@ impl Default for ProjectCategory {
|
||||
Serialize,
|
||||
)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[cfg_attr(feature = "backend", PgType = "InvitationStateMapping")]
|
||||
pub enum InvitationState {
|
||||
#[default]
|
||||
Sent,
|
||||
Accepted,
|
||||
Revoked,
|
||||
}
|
||||
|
||||
impl Default for InvitationState {
|
||||
fn default() -> Self {
|
||||
InvitationState::Sent
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "backend", derive(DbEnum))]
|
||||
#[cfg_attr(feature = "backend", PgType = "TimeTrackingMapping")]
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Default,
|
||||
Deserialize,
|
||||
Display,
|
||||
EnumAsStr,
|
||||
EnumIter,
|
||||
EnumLabel,
|
||||
EnumString,
|
||||
EnumU32,
|
||||
Hash,
|
||||
IntoStaticStr,
|
||||
PartialEq,
|
||||
@ -225,18 +229,14 @@ impl Default for InvitationState {
|
||||
Serialize,
|
||||
)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[cfg_attr(feature = "backend", PgType = "TimeTrackingMapping")]
|
||||
pub enum TimeTracking {
|
||||
#[default]
|
||||
Untracked,
|
||||
Fibonacci,
|
||||
Hourly,
|
||||
}
|
||||
|
||||
impl Default for TimeTracking {
|
||||
fn default() -> Self {
|
||||
Self::Untracked
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize)]
|
||||
pub struct ErrorResponse {
|
||||
pub errors: Vec<String>,
|
||||
@ -386,9 +386,13 @@ pub struct IssueAssignee {
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Default,
|
||||
Deserialize,
|
||||
Display,
|
||||
EnumAsStr,
|
||||
EnumLabel,
|
||||
EnumString,
|
||||
EnumU32,
|
||||
Hash,
|
||||
IntoStaticStr,
|
||||
PartialEq,
|
||||
@ -396,18 +400,14 @@ pub struct IssueAssignee {
|
||||
Serialize,
|
||||
)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[cfg_attr(feature = "backend", PgType = "MessageTypeMapping")]
|
||||
pub enum MessageType {
|
||||
ReceivedInvitation,
|
||||
AssignedToIssue,
|
||||
#[default]
|
||||
Mention,
|
||||
}
|
||||
|
||||
impl Default for MessageType {
|
||||
fn default() -> Self {
|
||||
Self::Mention
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "backend", derive(Queryable))]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub struct Message {
|
||||
@ -475,10 +475,14 @@ pub struct HighlightedCode {
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Default,
|
||||
Deserialize,
|
||||
Display,
|
||||
EnumAsStr,
|
||||
EnumIter,
|
||||
EnumLabel,
|
||||
EnumString,
|
||||
EnumU32,
|
||||
Hash,
|
||||
IntoStaticStr,
|
||||
PartialEq,
|
||||
@ -488,18 +492,14 @@ pub struct HighlightedCode {
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[cfg_attr(feature = "backend", PgType = "TextEditorModeMapping")]
|
||||
#[repr(C)]
|
||||
#[cfg_attr(feature = "backend", PgType = "TextEditorModeMapping")]
|
||||
pub enum TextEditorMode {
|
||||
#[default]
|
||||
MdOnly,
|
||||
RteOnly,
|
||||
Mixed,
|
||||
}
|
||||
|
||||
impl Default for TextEditorMode {
|
||||
fn default() -> Self {
|
||||
TextEditorMode::MdOnly
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "backend", derive(Queryable))]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub struct UserSetting {
|
||||
|
@ -9,7 +9,7 @@ license = "MPL-2.0"
|
||||
#license-file = "../LICENSE"
|
||||
|
||||
[features]
|
||||
aws-s3 = ["cloud-storage-actor"]
|
||||
cloud-storage = ["cloud-storage-actor"]
|
||||
local-storage = ["filesystem-actor"]
|
||||
default = ["local-storage"]
|
||||
|
||||
|
@ -2,7 +2,9 @@
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
use actix::Actor;
|
||||
use actix_web::web::Data;
|
||||
use actix_web::{App, HttpServer};
|
||||
use tracing::info;
|
||||
use tracing_subscriber::util::SubscriberInitExt;
|
||||
|
||||
pub mod errors;
|
||||
@ -39,28 +41,30 @@ async fn main() -> Result<(), String> {
|
||||
#[cfg(feature = "local-storage")]
|
||||
let fs_addr = actix::SyncArbiter::start(
|
||||
bitque_config::fs::Configuration::read().concurrency,
|
||||
filesystem_actor::FileSystemExecutor::default,
|
||||
filesystem_actor::LocalStorageExecutor::default,
|
||||
);
|
||||
#[cfg(feature = "aws-s3")]
|
||||
let amazon_addr = actix::SyncArbiter::start(
|
||||
#[cfg(feature = "cloud-storage")]
|
||||
let cloud_storage_addr = actix::SyncArbiter::start(
|
||||
bitque_config::web::Configuration::read().concurrency,
|
||||
amazon_actor::AmazonExecutor::default,
|
||||
cloud_storage_actor::CloudStorageExecutor::default,
|
||||
);
|
||||
|
||||
let ws_server = websocket_actor::server::WsServer::start_default();
|
||||
|
||||
info!("Listen at {}", web_config.bind_addr());
|
||||
|
||||
HttpServer::new(move || {
|
||||
let app = App::new().wrap(actix_web::middleware::Logger::default());
|
||||
|
||||
// data step
|
||||
let app = app
|
||||
.app_data(ws_server.clone())
|
||||
.app_data(db_addr.clone())
|
||||
.app_data(mail_addr.clone())
|
||||
.app_data(hi_addr.clone())
|
||||
.app_data(database_actor::build_pool());
|
||||
featured! { app, "local-storage", app.app_data(fs_addr.clone()) };
|
||||
featured! { app, "aws-s3", app.data(amazon_addr.clone()) };
|
||||
.app_data(Data::new(ws_server.clone()))
|
||||
.app_data(Data::new(db_addr.clone()))
|
||||
.app_data(Data::new(mail_addr.clone()))
|
||||
.app_data(Data::new(hi_addr.clone()))
|
||||
.app_data(Data::new(database_actor::build_pool()));
|
||||
featured! { app, "local-storage", app.app_data(Data::new(fs_addr.clone())) };
|
||||
featured! { app, "cloud-storage", app.app_data(Data::new(cloud_storage_addr.clone())) };
|
||||
|
||||
// services step
|
||||
let app = app
|
||||
|
@ -14,15 +14,15 @@ pub enum AmazonError {
|
||||
Credentials,
|
||||
}
|
||||
|
||||
pub struct AmazonExecutor;
|
||||
pub struct CloudStorageExecutor;
|
||||
|
||||
impl Default for AmazonExecutor {
|
||||
impl Default for CloudStorageExecutor {
|
||||
fn default() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
impl actix::Actor for AmazonExecutor {
|
||||
impl actix::Actor for CloudStorageExecutor {
|
||||
type Context = actix::SyncContext<Self>;
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ pub struct S3PutObject {
|
||||
pub file_name: String,
|
||||
}
|
||||
|
||||
impl actix::Handler<S3PutObject> for AmazonExecutor {
|
||||
impl actix::Handler<S3PutObject> for CloudStorageExecutor {
|
||||
type Result = Result<String, AmazonError>;
|
||||
|
||||
fn handle(&mut self, msg: S3PutObject, _ctx: &mut Self::Context) -> Self::Result {
|
||||
@ -42,12 +42,12 @@ impl actix::Handler<S3PutObject> for AmazonExecutor {
|
||||
mut source,
|
||||
file_name,
|
||||
} = msg;
|
||||
bitque_config::amazon::config().set_variables();
|
||||
bitque_config::cloud_storage::config().set_variables();
|
||||
|
||||
tokio::runtime::Runtime::new()
|
||||
.expect("Failed to start amazon agent")
|
||||
.block_on(async {
|
||||
let s3 = bitque_config::amazon::config();
|
||||
let s3 = bitque_config::cloud_storage::config();
|
||||
tracing::debug!("{:?}", s3);
|
||||
|
||||
let mut v: Vec<u8> = Vec::with_capacity(1024 * 1024 * 16);
|
||||
@ -55,7 +55,7 @@ impl actix::Handler<S3PutObject> for AmazonExecutor {
|
||||
v.extend_from_slice(&b)
|
||||
}
|
||||
|
||||
let config = bitque_config::amazon::config();
|
||||
let config = bitque_config::cloud_storage::config();
|
||||
let bucket = s3::Bucket::new(
|
||||
config.bucket.as_str(),
|
||||
Region::from_str(config.region_name.as_str()).unwrap(),
|
||||
|
@ -4,7 +4,7 @@ use diesel::prelude::*;
|
||||
|
||||
use crate::models::Issue;
|
||||
|
||||
#[derive(derive_db_execute::Execute, Default)]
|
||||
#[derive(Default, derive_db_execute::Execute)]
|
||||
#[db_exec(
|
||||
result = "Issue",
|
||||
schema = "issues",
|
||||
@ -24,7 +24,7 @@ pub struct LoadProjectIssues {
|
||||
pub project_id: ProjectId,
|
||||
}
|
||||
|
||||
#[derive(derive_db_execute::Execute, Default)]
|
||||
#[derive(Default, derive_db_execute::Execute)]
|
||||
#[db_exec(result = "Issue", schema = "issues")]
|
||||
pub struct UpdateIssue {
|
||||
pub issue_id: bitque_data::IssueId,
|
||||
|
@ -2,12 +2,11 @@ extern crate proc_macro;
|
||||
|
||||
use proc_macro::{TokenStream, TokenTree};
|
||||
|
||||
fn into_str(name: &str, variants: &[String]) -> String {
|
||||
fn as_str(name: &str, variants: &[String]) -> String {
|
||||
let mut code = format!(
|
||||
r#"
|
||||
#[cfg(feature = "frontend")]
|
||||
impl {name} {{
|
||||
pub fn to_str(&self) -> &'static str {{
|
||||
pub fn as_str(&self) -> &'static str {{
|
||||
match self {{
|
||||
"#,
|
||||
name = name,
|
||||
@ -32,8 +31,7 @@ impl {name} {{
|
||||
fn from_str(name: &str, variants: &[String]) -> String {
|
||||
let mut code = format!(
|
||||
r#"
|
||||
#[cfg(feature = "frontend")]
|
||||
impl FromStr for {name} {{
|
||||
impl std::str::FromStr for {name} {{
|
||||
type Err = String;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {{
|
||||
match s {{
|
||||
@ -68,7 +66,6 @@ impl FromStr for {name} {{
|
||||
fn into_label(name: &str, variants: &[String]) -> String {
|
||||
let mut code = format!(
|
||||
r#"
|
||||
#[cfg(feature = "frontend")]
|
||||
impl {name} {{
|
||||
pub fn to_label(&self) -> &'static str {{
|
||||
match self {{
|
||||
@ -139,16 +136,128 @@ impl Into<{name}> for u32 {{
|
||||
code
|
||||
}
|
||||
|
||||
#[proc_macro_derive(EnumPrimitive)]
|
||||
pub fn derive_enum_primitive(item: TokenStream) -> TokenStream {
|
||||
#[proc_macro_derive(EnumU32)]
|
||||
pub fn derive_enum_u32(item: TokenStream) -> TokenStream {
|
||||
let mut it = item.into_iter().peekable();
|
||||
|
||||
while let Some(token) = it.peek() {
|
||||
if let TokenTree::Ident(_) = token {
|
||||
match token {
|
||||
TokenTree::Ident(_) => {
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
it.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(TokenTree::Ident(ident)) = it.next() {
|
||||
if ident.to_string().as_str() != "pub" {
|
||||
panic!("Expect to find keyword pub but was found {:?}", ident)
|
||||
}
|
||||
} else {
|
||||
panic!("Expect to find keyword pub but nothing was found")
|
||||
}
|
||||
if let Some(TokenTree::Ident(ident)) = it.next() {
|
||||
if ident.to_string().as_str() != "enum" {
|
||||
panic!("Expect to find keyword struct but was found {:?}", ident)
|
||||
}
|
||||
} else {
|
||||
panic!("Expect to find keyword struct but nothing was found")
|
||||
}
|
||||
let name = it
|
||||
.next()
|
||||
.expect("Expect to struct name but nothing was found")
|
||||
.to_string();
|
||||
|
||||
let mut variants = vec![];
|
||||
if let Some(TokenTree::Group(group)) = it.next() {
|
||||
for token in group.stream() {
|
||||
if let TokenTree::Ident(ident) = token {
|
||||
variants.push(ident.to_string())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic!("Enum variants group expected");
|
||||
}
|
||||
if variants.is_empty() {
|
||||
panic!("Enum cannot be empty")
|
||||
}
|
||||
|
||||
let mut code = String::new();
|
||||
code.push_str(into_u32(&name, &variants).as_str());
|
||||
code.push_str(from_u32(&name, &variants).as_str());
|
||||
code.parse().unwrap()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(EnumLabel)]
|
||||
pub fn derive_enum_label(item: TokenStream) -> TokenStream {
|
||||
let mut it = item.into_iter().peekable();
|
||||
|
||||
while let Some(token) = it.peek() {
|
||||
match token {
|
||||
TokenTree::Ident(_) => {
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
it.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(TokenTree::Ident(ident)) = it.next() {
|
||||
if ident.to_string().as_str() != "pub" {
|
||||
panic!("Expect to find keyword pub but was found {:?}", ident)
|
||||
}
|
||||
} else {
|
||||
panic!("Expect to find keyword pub but nothing was found")
|
||||
}
|
||||
if let Some(TokenTree::Ident(ident)) = it.next() {
|
||||
if ident.to_string().as_str() != "enum" {
|
||||
panic!("Expect to find keyword struct but was found {:?}", ident)
|
||||
}
|
||||
} else {
|
||||
panic!("Expect to find keyword struct but nothing was found")
|
||||
}
|
||||
let name = it
|
||||
.next()
|
||||
.expect("Expect to struct name but nothing was found")
|
||||
.to_string();
|
||||
|
||||
let mut variants = vec![];
|
||||
if let Some(TokenTree::Group(group)) = it.next() {
|
||||
for token in group.stream() {
|
||||
if let TokenTree::Ident(ident) = token {
|
||||
variants.push(ident.to_string())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic!("Enum variants group expected");
|
||||
}
|
||||
if variants.is_empty() {
|
||||
panic!("Enum cannot be empty")
|
||||
}
|
||||
|
||||
let mut code = String::new();
|
||||
code.push_str(into_label(&name, &variants).as_str());
|
||||
code.parse().unwrap()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(EnumStr)]
|
||||
pub fn derive_enum_str(item: TokenStream) -> TokenStream {
|
||||
let mut it = item.into_iter().peekable();
|
||||
|
||||
while let Some(token) = it.peek() {
|
||||
match token {
|
||||
TokenTree::Ident(_) => {
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
it.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(TokenTree::Ident(ident)) = it.next() {
|
||||
if ident.to_string().as_str() != "pub" {
|
||||
panic!("Expect to find keyword pub but was found {:?}", ident)
|
||||
@ -185,10 +294,61 @@ pub fn derive_enum_primitive(item: TokenStream) -> TokenStream {
|
||||
let mut code = String::new();
|
||||
|
||||
code.push_str(from_str(&name, &variants).as_str());
|
||||
code.push_str(into_str(&name, &variants).as_str());
|
||||
code.push_str(into_label(&name, &variants).as_str());
|
||||
code.push_str(into_u32(&name, &variants).as_str());
|
||||
code.push_str(from_u32(&name, &variants).as_str());
|
||||
|
||||
code.parse().unwrap()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(EnumAsStr)]
|
||||
pub fn derive_enum_as_str(item: TokenStream) -> TokenStream {
|
||||
let mut it = item.into_iter().peekable();
|
||||
|
||||
while let Some(token) = it.peek() {
|
||||
match token {
|
||||
TokenTree::Ident(_) => {
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
it.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(TokenTree::Ident(ident)) = it.next() {
|
||||
if ident.to_string().as_str() != "pub" {
|
||||
panic!("Expect to find keyword pub but was found {:?}", ident)
|
||||
}
|
||||
} else {
|
||||
panic!("Expect to find keyword pub but nothing was found")
|
||||
}
|
||||
if let Some(TokenTree::Ident(ident)) = it.next() {
|
||||
if ident.to_string().as_str() != "enum" {
|
||||
panic!("Expect to find keyword struct but was found {:?}", ident)
|
||||
}
|
||||
} else {
|
||||
panic!("Expect to find keyword struct but nothing was found")
|
||||
}
|
||||
let name = it
|
||||
.next()
|
||||
.expect("Expect to struct name but nothing was found")
|
||||
.to_string();
|
||||
|
||||
let mut variants = vec![];
|
||||
if let Some(TokenTree::Group(group)) = it.next() {
|
||||
for token in group.stream() {
|
||||
if let TokenTree::Ident(ident) = token {
|
||||
variants.push(ident.to_string())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic!("Enum variants group expected");
|
||||
}
|
||||
if variants.is_empty() {
|
||||
panic!("Enum cannot be empty")
|
||||
}
|
||||
|
||||
let mut code = String::new();
|
||||
|
||||
code.push_str(as_str(&name, &variants).as_str());
|
||||
|
||||
code.parse().unwrap()
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ fn val_from_attrs(attrs: &[Attribute], attr_name: &str) -> Option<String> {
|
||||
|
||||
/// Defines the casing for the database representation. Follows serde naming
|
||||
/// convention.
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
enum CaseStyle {
|
||||
Camel,
|
||||
Kebab,
|
||||
|
@ -13,11 +13,11 @@ pub enum FsError {
|
||||
WriteFile,
|
||||
}
|
||||
|
||||
pub struct FileSystemExecutor {
|
||||
pub struct LocalStorageExecutor {
|
||||
config: Configuration,
|
||||
}
|
||||
|
||||
impl FileSystemExecutor {
|
||||
impl LocalStorageExecutor {
|
||||
pub fn client_path(&self) -> &str {
|
||||
self.config.client_path.as_str()
|
||||
}
|
||||
@ -27,7 +27,7 @@ impl FileSystemExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FileSystemExecutor {
|
||||
impl Default for LocalStorageExecutor {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
config: Configuration::read(),
|
||||
@ -35,7 +35,7 @@ impl Default for FileSystemExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
impl actix::Actor for FileSystemExecutor {
|
||||
impl actix::Actor for LocalStorageExecutor {
|
||||
type Context = SyncContext<Self>;
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ pub struct CreateFile {
|
||||
pub file_name: String,
|
||||
}
|
||||
|
||||
impl actix::Handler<CreateFile> for FileSystemExecutor {
|
||||
impl actix::Handler<CreateFile> for LocalStorageExecutor {
|
||||
type Result = Result<usize, FsError>;
|
||||
|
||||
fn handle(&mut self, msg: CreateFile, _ctx: &mut Self::Context) -> Self::Result {
|
||||
|
1725
crates/highlight-actor/assets/InspiredGitHub.tmTheme
Normal file
@ -75,7 +75,7 @@ impl HighlightActor {
|
||||
.theme_set
|
||||
.as_ref()
|
||||
.themes
|
||||
.get("GitHub")
|
||||
.get("InspiredGitHub")
|
||||
.ok_or(HighlightError::UnknownTheme)?;
|
||||
|
||||
let mut hi = HighlightLines::new(set, theme);
|
||||
|
@ -1,24 +1,12 @@
|
||||
use std::io::BufRead;
|
||||
|
||||
use bincode::{deserialize_from, Result};
|
||||
use flate2::bufread::ZlibDecoder;
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
fn from_reader<T: DeserializeOwned, R: BufRead>(input: R) -> Result<T> {
|
||||
let mut decoder = ZlibDecoder::new(input);
|
||||
deserialize_from(&mut decoder)
|
||||
}
|
||||
|
||||
fn from_binary<T: DeserializeOwned>(v: &[u8]) -> T {
|
||||
from_reader(v).unwrap()
|
||||
}
|
||||
use syntect::highlighting::ThemeSet;
|
||||
use syntect::parsing::SyntaxSet;
|
||||
|
||||
#[inline(always)]
|
||||
pub fn integrated_syntaxset() -> syntect::parsing::SyntaxSet {
|
||||
from_binary(include_bytes!("./syntaxes.bin"))
|
||||
SyntaxSet::load_defaults_newlines()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn integrated_themeset() -> syntect::highlighting::ThemeSet {
|
||||
from_binary(include_bytes!("./themes.bin"))
|
||||
ThemeSet::load_defaults()
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ path = "./src/lib.rs"
|
||||
|
||||
[features]
|
||||
local-storage = ["filesystem-actor"]
|
||||
aws-s3 = ["cloud-storage-actor"]
|
||||
cloud-storage = ["cloud-storage-actor"]
|
||||
default = ["local-storage"]
|
||||
|
||||
[dependencies]
|
||||
|
@ -4,29 +4,28 @@ use actix::Addr;
|
||||
use actix_multipart::{Field, Multipart};
|
||||
use actix_web::web::Data;
|
||||
use actix_web::{post, web, Error, HttpResponse};
|
||||
use bitque_data::msg::{WsMsg, WsMsgUser};
|
||||
use bitque_data::msg::WsMsgUser;
|
||||
use bitque_data::{User, UserId};
|
||||
use database_actor::authorize_user::AuthorizeUser;
|
||||
use database_actor::user_projects::CurrentUserProject;
|
||||
use database_actor::users::UpdateAvatarUrl;
|
||||
use database_actor::DbExecutor;
|
||||
#[cfg(feature = "local-storage")]
|
||||
use futures::executor::block_on;
|
||||
use futures::{StreamExt, TryStreamExt};
|
||||
use tracing::error;
|
||||
use tracing::{error, warn};
|
||||
use websocket_actor::server::InnerMsg::BroadcastToChannel;
|
||||
use websocket_actor::server::WsServer;
|
||||
|
||||
use crate::ServiceError;
|
||||
|
||||
#[cfg(feature = "aws-s3")]
|
||||
#[cfg(feature = "cloud-storage")]
|
||||
#[post("/")]
|
||||
pub async fn upload(
|
||||
mut payload: Multipart,
|
||||
db: Data<Addr<DbExecutor>>,
|
||||
ws: Data<Addr<WsServer>>,
|
||||
fs: Data<Addr<filesystem_actor::FileSystemExecutor>>,
|
||||
amazon: Data<Addr<amazon_actor::AmazonExecutor>>,
|
||||
fs: Data<Addr<filesystem_actor::LocalStorageExecutor>>,
|
||||
cloud_storage: Data<Addr<cloud_storage_actor::CloudStorageExecutor>>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let mut user_id: Option<UserId> = None;
|
||||
let mut avatar_url: Option<String> = None;
|
||||
@ -41,14 +40,16 @@ pub async fn upload(
|
||||
user_id = Some(handle_token(field, db.clone()).await?);
|
||||
}
|
||||
Some("avatar") => {
|
||||
let id = user_id.ok_or_else(|| HttpResponse::Unauthorized().finish())?;
|
||||
let Some(id) = user_id else {
|
||||
warn!("user id not found. Not authorized");
|
||||
return Ok(ServiceError::Unauthorized.into());
|
||||
};
|
||||
avatar_url = Some(
|
||||
crate::handlers::upload_avatar_image::handle_image(
|
||||
id,
|
||||
field,
|
||||
disposition.clone(),
|
||||
fs.clone(),
|
||||
amazon.clone(),
|
||||
cloud_storage.clone(),
|
||||
)
|
||||
.await?,
|
||||
);
|
||||
@ -56,6 +57,10 @@ pub async fn upload(
|
||||
_ => continue,
|
||||
};
|
||||
}
|
||||
|
||||
tracing::info!("user_id {user_id:?}");
|
||||
tracing::info!("token {avatar_url:?}");
|
||||
|
||||
let user_id = match user_id {
|
||||
Some(id) => id,
|
||||
_ => return Ok(HttpResponse::Unauthorized().finish()),
|
||||
@ -69,25 +74,26 @@ pub async fn upload(
|
||||
match (user_id, avatar_url) {
|
||||
(user_id, Some(avatar_url)) => {
|
||||
let user = update_user_avatar(user_id, avatar_url.clone(), db).await?;
|
||||
ws.send(BroadcastToChannel(
|
||||
let Ok(_) = ws.send(BroadcastToChannel(
|
||||
project_id,
|
||||
WsMsgUser::AvatarUrlChanged(user.id, avatar_url).into(),
|
||||
))
|
||||
.await
|
||||
.map_err(|_| HttpResponse::UnprocessableEntity().finish())?;
|
||||
.await else {
|
||||
return Ok(HttpResponse::UnprocessableEntity().finish());
|
||||
};
|
||||
Ok(HttpResponse::NoContent().finish())
|
||||
}
|
||||
_ => Ok(HttpResponse::UnprocessableEntity().finish()),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "aws-s3"))]
|
||||
#[cfg(not(feature = "cloud-storage"))]
|
||||
#[post("/")]
|
||||
pub async fn upload(
|
||||
mut payload: Multipart,
|
||||
db: Data<Addr<DbExecutor>>,
|
||||
ws: Data<Addr<WsServer>>,
|
||||
fs: Data<Addr<filesystem_actor::FileSystemExecutor>>,
|
||||
fs: Data<Addr<filesystem_actor::LocalStorageExecutor>>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let mut user_id: Option<UserId> = None;
|
||||
let mut avatar_url: Option<String> = None;
|
||||
@ -144,7 +150,7 @@ async fn update_user_avatar(
|
||||
user_id: UserId,
|
||||
new_url: String,
|
||||
db: Data<Addr<DbExecutor>>,
|
||||
) -> Result<User, actix_web::Error> {
|
||||
) -> Result<User, Error> {
|
||||
match db
|
||||
.send(UpdateAvatarUrl {
|
||||
user_id,
|
||||
@ -155,11 +161,11 @@ async fn update_user_avatar(
|
||||
Ok(Ok(user)) => Ok(user),
|
||||
|
||||
Ok(Err(e)) => {
|
||||
::tracing::error!("{:?}", e);
|
||||
error!("{:?}", e);
|
||||
Err(ServiceError::Unauthorized.into())
|
||||
}
|
||||
Err(e) => {
|
||||
::tracing::error!("{:?}", e);
|
||||
error!("{:?}", e);
|
||||
Err(ServiceError::Unauthorized.into())
|
||||
}
|
||||
}
|
||||
@ -185,11 +191,11 @@ async fn handle_token(mut field: Field, db: Data<Addr<DbExecutor>>) -> Result<Us
|
||||
Ok(Ok(user)) => Ok(user.id),
|
||||
|
||||
Ok(Err(e)) => {
|
||||
::tracing::error!("{:?}", e);
|
||||
error!("{:?}", e);
|
||||
Err(ServiceError::Unauthorized.into())
|
||||
}
|
||||
Err(e) => {
|
||||
::tracing::error!("{:?}", e);
|
||||
error!("{:?}", e);
|
||||
Err(ServiceError::Unauthorized.into())
|
||||
}
|
||||
}
|
||||
|
@ -8,14 +8,14 @@ use bitque_data::ErrorResponse;
|
||||
const TOKEN_NOT_FOUND: &str = "Token not found";
|
||||
const DATABASE_CONNECTION_FAILED: &str = "Database connection failed";
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum HighlightError {
|
||||
UnknownLanguage,
|
||||
UnknownTheme,
|
||||
ResultUnserializable,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ServiceError {
|
||||
Unauthorized,
|
||||
DatabaseConnectionLost,
|
||||
|
@ -1,18 +1,19 @@
|
||||
use actix::Addr;
|
||||
use actix::{spawn, Addr};
|
||||
use actix_multipart::Field;
|
||||
use actix_web::web::Data;
|
||||
use actix_web::Error;
|
||||
use actix_web::{Error, HttpResponse};
|
||||
use bitque_data::UserId;
|
||||
use futures::future::join_all;
|
||||
use futures::StreamExt;
|
||||
use tokio::sync::broadcast::{Receiver, Sender};
|
||||
use tracing::error;
|
||||
|
||||
#[cfg(all(feature = "local-storage", feature = "aws-s3"))]
|
||||
#[cfg(all(feature = "local-storage", feature = "cloud-storage"))]
|
||||
pub(crate) async fn handle_image(
|
||||
user_id: UserId,
|
||||
mut field: Field,
|
||||
fs: Data<Addr<filesystem_actor::FileSystemExecutor>>,
|
||||
amazon: Data<Addr<amazon_actor::AmazonExecutor>>,
|
||||
fs: Data<Addr<filesystem_actor::LocalStorageExecutor>>,
|
||||
cloud_storage: Data<Addr<cloud_storage_actor::CloudStorageExecutor>>,
|
||||
) -> Result<String, Error> {
|
||||
let filename = field.content_disposition().get_filename().unwrap();
|
||||
let system_file_name = format!("{}-{}", user_id, filename);
|
||||
@ -20,38 +21,35 @@ pub(crate) async fn handle_image(
|
||||
let (sender, receiver) = tokio::sync::broadcast::channel(64);
|
||||
|
||||
let fs_fut = local_storage_write(system_file_name.clone(), fs, user_id, sender.subscribe());
|
||||
let aws_fut = aws_s3(system_file_name, amazon, receiver);
|
||||
let aws_fut = cloud_storage_write(system_file_name, cloud_storage, receiver);
|
||||
let read_fut = read_form_data(&mut field, sender);
|
||||
|
||||
let fs_join = tokio::task::spawn(fs_fut);
|
||||
let aws_join = tokio::task::spawn(aws_fut);
|
||||
read_fut.await;
|
||||
|
||||
let mut new_link = None;
|
||||
let results = join_all([spawn(fs_fut), spawn(aws_fut)]).await;
|
||||
|
||||
if let Ok(url) = fs_join.await {
|
||||
new_link = url;
|
||||
for res in results {
|
||||
return if let Ok(Some(link)) = res {
|
||||
Ok(link)
|
||||
} else {
|
||||
Err(HttpResponse::UnprocessableEntity().finish().into())
|
||||
};
|
||||
}
|
||||
|
||||
if let Ok(url) = aws_join.await {
|
||||
new_link = url;
|
||||
}
|
||||
|
||||
Ok(new_link.unwrap_or_default())
|
||||
Err(HttpResponse::UnprocessableEntity().finish().into())
|
||||
}
|
||||
|
||||
#[cfg(all(not(feature = "local-storage"), feature = "aws-s3"))]
|
||||
#[cfg(all(not(feature = "local-storage"), feature = "cloud-storage"))]
|
||||
pub(crate) async fn handle_image(
|
||||
user_id: UserId,
|
||||
mut field: Field,
|
||||
amazon: Data<Addr<amazon_actor::AmazonExecutor>>,
|
||||
cloud_storage: Data<Addr<cloud_storage_actor::CloudStorageExecutor>>,
|
||||
) -> Result<String, Error> {
|
||||
let filename = field.content_disposition().get_filename().unwrap();
|
||||
let system_file_name = format!("{}-{}", user_id, filename);
|
||||
|
||||
let (sender, receiver) = tokio::sync::broadcast::channel(64);
|
||||
|
||||
let aws_fut = aws_s3(system_file_name, amazon, receiver);
|
||||
let aws_fut = cloud - storage_write(system_file_name, cloud_storage, receiver);
|
||||
let read_fut = read_form_data(&mut field, sender);
|
||||
|
||||
let aws_join = tokio::task::spawn(aws_fut);
|
||||
@ -66,11 +64,11 @@ pub(crate) async fn handle_image(
|
||||
Ok(new_link.unwrap_or_default())
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "local-storage", not(feature = "aws-s3")))]
|
||||
#[cfg(all(feature = "local-storage", not(feature = "cloud-storage")))]
|
||||
pub(crate) async fn handle_image(
|
||||
user_id: UserId,
|
||||
mut field: Field,
|
||||
fs: Data<Addr<filesystem_actor::FileSystemExecutor>>,
|
||||
fs: Data<Addr<filesystem_actor::LocalStorageExecutor>>,
|
||||
) -> Result<String, Error> {
|
||||
let filename = field.content_disposition().get_filename().unwrap();
|
||||
let system_file_name = format!("{}-{}", user_id, filename);
|
||||
@ -103,19 +101,19 @@ async fn read_form_data(field: &mut Field, sender: Sender<bytes::Bytes>) {
|
||||
}
|
||||
|
||||
/// Stream bytes directly to AWS S3 Service
|
||||
#[cfg(feature = "aws-s3")]
|
||||
async fn aws_s3(
|
||||
#[cfg(feature = "cloud-storage")]
|
||||
async fn cloud_storage_write(
|
||||
system_file_name: String,
|
||||
amazon: Data<Addr<amazon_actor::AmazonExecutor>>,
|
||||
cloud_storage: Data<Addr<cloud_storage_actor::CloudStorageExecutor>>,
|
||||
receiver: Receiver<bytes::Bytes>,
|
||||
) -> Option<String> {
|
||||
let s3 = bitque_config::amazon::config();
|
||||
let s3 = bitque_config::cloud_storage::config();
|
||||
if !s3.active {
|
||||
return None;
|
||||
}
|
||||
|
||||
match amazon
|
||||
.send(amazon_actor::S3PutObject {
|
||||
match cloud_storage
|
||||
.send(cloud_storage_actor::S3PutObject {
|
||||
source: receiver,
|
||||
file_name: system_file_name.to_string(),
|
||||
})
|
||||
@ -129,7 +127,7 @@ async fn aws_s3(
|
||||
#[cfg(feature = "local-storage")]
|
||||
async fn local_storage_write(
|
||||
system_file_name: String,
|
||||
fs: Data<Addr<filesystem_actor::FileSystemExecutor>>,
|
||||
fs: Data<Addr<filesystem_actor::LocalStorageExecutor>>,
|
||||
_user_id: bitque_data::UserId,
|
||||
receiver: Receiver<bytes::Bytes>,
|
||||
) -> Option<String> {
|
||||
|
@ -8,11 +8,6 @@ repository = "https://gitlab.com/adrian.wozniak/bitque"
|
||||
license = "MPL-2.0"
|
||||
#license-file = "../LICENSE"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
name = "bitque_client"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[features]
|
||||
print-model = []
|
||||
default = []
|
||||
@ -25,16 +20,20 @@ console_error_panic_hook = { version = "*" }
|
||||
derive_enum_iter = { workspace = true }
|
||||
derive_enum_primitive = { workspace = true }
|
||||
dotenv = { version = "*" }
|
||||
futures = "0.3.6"
|
||||
futures = { version = "0.3.6" }
|
||||
js-sys = { version = "*", default-features = false }
|
||||
seed = { version = "0" }
|
||||
serde = { version = "1", features = [] }
|
||||
seed = { version = "0", features = ['serde-wasm-bindgen'] }
|
||||
serde = { version = "1", features = ['derive'] }
|
||||
serde_json = { version = "*" }
|
||||
tracing = { version = "0.1.37" }
|
||||
tracing-subscriber = { version = "0.3.16" }
|
||||
tracing-subscriber-wasm = { version = "0.1.0" }
|
||||
uuid = { version = "1.3.0", features = ["serde"] }
|
||||
wasm-bindgen = { version = "*", features = ["enable-interning"] }
|
||||
wasm-bindgen-futures = { version = "*" }
|
||||
wee_alloc = { version = "*", features = ["static_array_backend"] }
|
||||
wasm-sockets = { version = "1", features = [] }
|
||||
strum = { version = "*" }
|
||||
|
||||
[dependencies.web-sys]
|
||||
version = "*"
|
||||
|
20
crates/web/Trunk.toml
Normal file
@ -0,0 +1,20 @@
|
||||
[build]
|
||||
target = "./index.html"
|
||||
|
||||
[watch]
|
||||
ignore = [
|
||||
"tmp",
|
||||
]
|
||||
|
||||
[[hooks]]
|
||||
stage = "build"
|
||||
command = "zsh"
|
||||
command_arguments = ['./scripts/compile-css.sh']
|
||||
|
||||
[[proxy]]
|
||||
rewrite = "/ws"
|
||||
backend = "http://0.0.0.0:5000"
|
||||
|
||||
[[proxy]]
|
||||
rewrite = "/avatar"
|
||||
backend = "http://0.0.0.0:5000/avatar"
|
Before Width: | Height: | Size: 473 KiB After Width: | Height: | Size: 473 KiB |
Before Width: | Height: | Size: 605 KiB After Width: | Height: | Size: 605 KiB |
Before Width: | Height: | Size: 467 KiB After Width: | Height: | Size: 467 KiB |
Before Width: | Height: | Size: 604 KiB After Width: | Height: | Size: 604 KiB |
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 2.3 MiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |