Add cloud storage, fix upload and move to trunk
@ -82,9 +82,9 @@ fabric.properties
|
|||||||
|
|
||||||
/tmp/
|
/tmp/
|
||||||
|
|
||||||
/web/target/
|
crates/web/target/
|
||||||
/web/tmp/
|
crates/web/tmp/
|
||||||
/web/build/
|
crates/web/build/
|
||||||
|
|
||||||
/bitque-server/target/
|
crates/bitque-server/target/
|
||||||
/bitque-server/tmp/
|
crates/bitque-server/tmp/
|
||||||
|
2
.env
@ -1,5 +1,5 @@
|
|||||||
DEBUG=true
|
DEBUG=true
|
||||||
RUST_LOG=debug
|
RUST_LOG=info
|
||||||
JIRS_CLIENT_PORT=80
|
JIRS_CLIENT_PORT=80
|
||||||
JIRS_CLIENT_BIND=bitque.lvh.me
|
JIRS_CLIENT_BIND=bitque.lvh.me
|
||||||
DATABASE_URL=postgres://postgres@localhost:5432/bitque
|
DATABASE_URL=postgres://postgres@localhost:5432/bitque
|
||||||
|
35
.gitignore
vendored
@ -1,27 +1,12 @@
|
|||||||
/target
|
/target
|
||||||
|
/crates/bitque-client/pkg
|
||||||
mail.toml
|
/crates/bitque-client/tmp
|
||||||
mail.test.toml
|
/crates/bitque-client/build
|
||||||
web.toml
|
/crates/bitque-server/target
|
||||||
web.test.toml
|
/crates/bitque-cli/target
|
||||||
db.toml
|
/crates/bitque-bat/bat
|
||||||
db.test.toml
|
/crates/highlight/bitque-highlight/build
|
||||||
fs.toml
|
/crates/bitque-client/src/location.rs
|
||||||
fs.test.toml
|
/uploads
|
||||||
highlight.toml
|
/config
|
||||||
highlight.test.toml
|
|
||||||
|
|
||||||
pkg
|
|
||||||
bitque-client/pkg
|
|
||||||
bitque-client/tmp
|
|
||||||
bitque-client/build
|
|
||||||
tmp
|
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",
|
"ahash 0.7.6",
|
||||||
"bytes",
|
"bytes",
|
||||||
"bytestring",
|
"bytestring",
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"cookie",
|
"cookie",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
@ -321,7 +321,7 @@ version = "0.8.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
|
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"version_check 0.9.4",
|
"version_check 0.9.4",
|
||||||
@ -400,6 +400,12 @@ dependencies = [
|
|||||||
"windows-sys 0.45.0",
|
"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]]
|
[[package]]
|
||||||
name = "ascii_utils"
|
name = "ascii_utils"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
@ -601,6 +607,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"actix",
|
"actix",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"derive_enum_primitive",
|
||||||
"diesel 2.0.3",
|
"diesel 2.0.3",
|
||||||
"diesel-derive-enum 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"diesel-derive-enum 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"diesel-derive-more",
|
"diesel-derive-more",
|
||||||
@ -611,6 +618,35 @@ dependencies = [
|
|||||||
"uuid 1.3.0",
|
"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]]
|
[[package]]
|
||||||
name = "bitquec"
|
name = "bitquec"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -693,6 +729,12 @@ dependencies = [
|
|||||||
"jobserver",
|
"jobserver",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -825,6 +867,16 @@ dependencies = [
|
|||||||
"windows-sys 0.45.0",
|
"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]]
|
[[package]]
|
||||||
name = "convert_case"
|
name = "convert_case"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -873,7 +925,7 @@ version = "1.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -882,7 +934,7 @@ version = "0.5.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c"
|
checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -892,7 +944,7 @@ version = "0.8.15"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
|
checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1042,6 +1094,15 @@ dependencies = [
|
|||||||
"uuid 1.3.0",
|
"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]]
|
[[package]]
|
||||||
name = "derive_db_execute"
|
name = "derive_db_execute"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -1250,6 +1311,12 @@ version = "0.2.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112"
|
checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enclose"
|
||||||
|
version = "1.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1056f553da426e9c025a662efa48b52e62e0a3a7648aa2d15aeaaf7f0d329357"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding"
|
name = "encoding"
|
||||||
version = "0.2.33"
|
version = "0.2.33"
|
||||||
@ -1320,7 +1387,7 @@ version = "0.8.32"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
|
checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1552,9 +1619,179 @@ 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 = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"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]]
|
[[package]]
|
||||||
@ -1781,7 +2018,7 @@ version = "0.1.12"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1981,7 +2218,7 @@ version = "0.4.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2040,6 +2277,12 @@ version = "2.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memory_units"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
@ -2211,7 +2454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2"
|
checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"foreign-types",
|
"foreign-types",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@ -2291,7 +2534,7 @@ version = "0.9.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall 0.2.16",
|
"redox_syscall 0.2.16",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
@ -2316,6 +2559,26 @@ 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 = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
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]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.9"
|
version = "0.2.9"
|
||||||
@ -2734,7 +2997,7 @@ version = "0.18.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df"
|
checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"ordered-multimap",
|
"ordered-multimap",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2748,7 +3011,7 @@ dependencies = [
|
|||||||
"aws-creds",
|
"aws-creds",
|
||||||
"aws-region",
|
"aws-region",
|
||||||
"base64 0.13.1",
|
"base64 0.13.1",
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"hex",
|
"hex",
|
||||||
"hmac",
|
"hmac",
|
||||||
"http",
|
"http",
|
||||||
@ -2870,6 +3133,12 @@ dependencies = [
|
|||||||
"parking_lot",
|
"parking_lot",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scoped-tls"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@ -2905,6 +3174,34 @@ dependencies = [
|
|||||||
"libc",
|
"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]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.17"
|
version = "1.0.17"
|
||||||
@ -2920,6 +3217,17 @@ dependencies = [
|
|||||||
"serde_derive",
|
"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]]
|
[[package]]
|
||||||
name = "serde-xml-rs"
|
name = "serde-xml-rs"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@ -2990,7 +3298,7 @@ version = "0.10.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
@ -3007,7 +3315,7 @@ version = "0.10.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
|
checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
@ -3110,6 +3418,12 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "static_assertions"
|
name = "static_assertions"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@ -3224,7 +3538,7 @@ version = "3.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
|
checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"redox_syscall 0.3.5",
|
"redox_syscall 0.3.5",
|
||||||
"rustix 0.37.5",
|
"rustix 0.37.5",
|
||||||
@ -3300,7 +3614,7 @@ version = "1.1.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
|
checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3468,7 +3782,7 @@ version = "0.1.37"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"log",
|
"log",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"tracing-attributes",
|
"tracing-attributes",
|
||||||
@ -3526,6 +3840,17 @@ dependencies = [
|
|||||||
"tracing-log",
|
"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]]
|
[[package]]
|
||||||
name = "triple_accel"
|
name = "triple_accel"
|
||||||
version = "0.3.4"
|
version = "0.3.4"
|
||||||
@ -3717,7 +4042,9 @@ version = "0.2.84"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
|
checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3742,7 +4069,7 @@ version = "0.4.34"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
|
checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
@ -3777,6 +4104,43 @@ version = "0.2.84"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
|
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]]
|
[[package]]
|
||||||
name = "wasm-streams"
|
name = "wasm-streams"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
@ -3854,6 +4218,19 @@ dependencies = [
|
|||||||
"uuid 1.3.0",
|
"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]]
|
[[package]]
|
||||||
name = "wildmatch"
|
name = "wildmatch"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
|
@ -26,7 +26,7 @@ members = [
|
|||||||
"./crates/cloud-storage-actor",
|
"./crates/cloud-storage-actor",
|
||||||
"./crates/filesystem-actor",
|
"./crates/filesystem-actor",
|
||||||
# Client
|
# Client
|
||||||
# "./crates/web"
|
"./crates/web"
|
||||||
]
|
]
|
||||||
exclude = [
|
exclude = [
|
||||||
"crates/bitque-cli",
|
"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"
|
path = "./src/lib.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
aws-s3 = ["rust-s3"]
|
cloud-storage = ["rust-s3"]
|
||||||
local-storage = []
|
local-storage = []
|
||||||
database = []
|
database = []
|
||||||
hi = []
|
hi = []
|
||||||
mail = []
|
mail = []
|
||||||
web = ["aws-s3", "local-storage"]
|
web = ["cloud-storage", "local-storage"]
|
||||||
websocket = []
|
websocket = []
|
||||||
default = ["local-storage", "database", "hi", "mail", "web", "websocket"]
|
default = ["local-storage", "database", "hi", "mail", "web", "websocket"]
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[cfg(feature = "aws-s3")]
|
#[cfg(feature = "cloud-storage")]
|
||||||
pub mod amazon;
|
pub mod cloud_storage;
|
||||||
|
|
||||||
#[cfg(feature = "database")]
|
#[cfg(feature = "database")]
|
||||||
pub mod database;
|
pub mod database;
|
||||||
|
@ -14,13 +14,14 @@ path = "./src/lib.rs"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
backend = ["diesel", "actix", "diesel-derive-newtype"]
|
backend = ["diesel", "actix", "diesel-derive-newtype"]
|
||||||
frontend = []
|
frontend = ['derive_enum_primitive']
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix = { version = "0.13.0", optional = true }
|
actix = { version = "0.13.0", optional = true }
|
||||||
chrono = { version = "*", features = ["serde"] }
|
chrono = { version = "*", features = ["serde"] }
|
||||||
diesel = { version = "2.0.3", features = ["postgres", "numeric", "uuid", "r2d2"], optional = true }
|
diesel = { version = "2.0.3", features = ["postgres", "numeric", "uuid", "r2d2"], optional = true }
|
||||||
diesel-derive-enum = { version = "2.0.1", features = ["postgres"] }
|
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-enum = { path = "../derive_enum_sql", features = ["postgres"] }
|
||||||
diesel-derive-more = { version = "1.1.3" }
|
diesel-derive-more = { version = "1.1.3" }
|
||||||
diesel-derive-newtype = { version = "2.0.0-rc.0", optional = true }
|
diesel-derive-newtype = { version = "2.0.0-rc.0", optional = true }
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
|
use derive_enum_primitive::*;
|
||||||
#[cfg(feature = "backend")]
|
#[cfg(feature = "backend")]
|
||||||
use diesel::*;
|
use diesel::*;
|
||||||
#[cfg(feature = "backend")]
|
#[cfg(feature = "backend")]
|
||||||
@ -55,10 +56,14 @@ pub type EndsAt = NaiveDateTime;
|
|||||||
Clone,
|
Clone,
|
||||||
Copy,
|
Copy,
|
||||||
Debug,
|
Debug,
|
||||||
|
Default,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
Display,
|
Display,
|
||||||
|
EnumAsStr,
|
||||||
EnumIter,
|
EnumIter,
|
||||||
|
EnumLabel,
|
||||||
EnumString,
|
EnumString,
|
||||||
|
EnumU32,
|
||||||
Hash,
|
Hash,
|
||||||
IntoStaticStr,
|
IntoStaticStr,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -66,27 +71,27 @@ pub type EndsAt = NaiveDateTime;
|
|||||||
Serialize,
|
Serialize,
|
||||||
)]
|
)]
|
||||||
#[strum(serialize_all = "snake_case")]
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
#[cfg_attr(feature = "backend", PgType = "IssueTypeMapping")]
|
||||||
pub enum IssueType {
|
pub enum IssueType {
|
||||||
|
#[default]
|
||||||
Task,
|
Task,
|
||||||
Bug,
|
Bug,
|
||||||
Story,
|
Story,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for IssueType {
|
|
||||||
fn default() -> Self {
|
|
||||||
IssueType::Task
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "backend", derive(DbEnum))]
|
#[cfg_attr(feature = "backend", derive(DbEnum))]
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone,
|
||||||
Copy,
|
Copy,
|
||||||
Debug,
|
Debug,
|
||||||
|
Default,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
Display,
|
Display,
|
||||||
|
EnumAsStr,
|
||||||
EnumIter,
|
EnumIter,
|
||||||
|
EnumLabel,
|
||||||
EnumString,
|
EnumString,
|
||||||
|
EnumU32,
|
||||||
Hash,
|
Hash,
|
||||||
IntoStaticStr,
|
IntoStaticStr,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -94,36 +99,38 @@ impl Default for IssueType {
|
|||||||
Serialize,
|
Serialize,
|
||||||
)]
|
)]
|
||||||
#[strum(serialize_all = "snake_case")]
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
#[cfg_attr(feature = "backend", PgType = "IssuePriorityMapping")]
|
||||||
pub enum IssuePriority {
|
pub enum IssuePriority {
|
||||||
Highest,
|
Highest,
|
||||||
High,
|
High,
|
||||||
|
#[default]
|
||||||
Medium,
|
Medium,
|
||||||
Low,
|
Low,
|
||||||
Lowest,
|
Lowest,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for IssuePriority {
|
|
||||||
fn default() -> Self {
|
|
||||||
IssuePriority::Medium
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "backend", derive(DbEnum))]
|
#[cfg_attr(feature = "backend", derive(DbEnum))]
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone,
|
||||||
Copy,
|
Copy,
|
||||||
Debug,
|
Debug,
|
||||||
|
Default,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
Display,
|
Display,
|
||||||
|
EnumAsStr,
|
||||||
EnumIter,
|
EnumIter,
|
||||||
|
EnumLabel,
|
||||||
EnumString,
|
EnumString,
|
||||||
|
EnumU32,
|
||||||
Hash,
|
Hash,
|
||||||
IntoStaticStr,
|
IntoStaticStr,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Serialize,
|
Serialize,
|
||||||
)]
|
)]
|
||||||
#[strum(serialize_all = "snake_case")]
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
#[cfg_attr(feature = "backend", PgType = "UserRoleMapping")]
|
||||||
pub enum UserRole {
|
pub enum UserRole {
|
||||||
|
#[default]
|
||||||
User,
|
User,
|
||||||
Manager,
|
Manager,
|
||||||
Owner,
|
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", derive(DbEnum))]
|
||||||
#[cfg_attr(feature = "backend", PgType = "ProjectCategoryMapping")]
|
#[cfg_attr(feature = "backend", PgType = "ProjectCategoryMapping")]
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone,
|
||||||
Copy,
|
Copy,
|
||||||
Debug,
|
Debug,
|
||||||
|
Default,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
Display,
|
Display,
|
||||||
|
EnumAsStr,
|
||||||
EnumIter,
|
EnumIter,
|
||||||
|
EnumLabel,
|
||||||
EnumString,
|
EnumString,
|
||||||
|
EnumU32,
|
||||||
Hash,
|
Hash,
|
||||||
IntoStaticStr,
|
IntoStaticStr,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -167,28 +172,27 @@ impl Default for UserRole {
|
|||||||
Serialize,
|
Serialize,
|
||||||
)]
|
)]
|
||||||
#[strum(serialize_all = "snake_case")]
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
#[cfg_attr(feature = "backend", PgType = "ProjectCategoryMapping")]
|
||||||
pub enum ProjectCategory {
|
pub enum ProjectCategory {
|
||||||
|
#[default]
|
||||||
Software,
|
Software,
|
||||||
Marketing,
|
Marketing,
|
||||||
Business,
|
Business,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ProjectCategory {
|
|
||||||
fn default() -> Self {
|
|
||||||
ProjectCategory::Software
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "backend", derive(DbEnum))]
|
#[cfg_attr(feature = "backend", derive(DbEnum))]
|
||||||
#[cfg_attr(feature = "backend", PgType = "InvitationStateMapping")]
|
#[cfg_attr(feature = "backend", PgType = "InvitationStateMapping")]
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone,
|
||||||
Copy,
|
Copy,
|
||||||
Debug,
|
Debug,
|
||||||
|
Default,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
Display,
|
Display,
|
||||||
|
EnumAsStr,
|
||||||
EnumIter,
|
EnumIter,
|
||||||
EnumString,
|
EnumString,
|
||||||
|
EnumU32,
|
||||||
Hash,
|
Hash,
|
||||||
IntoStaticStr,
|
IntoStaticStr,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -196,28 +200,28 @@ impl Default for ProjectCategory {
|
|||||||
Serialize,
|
Serialize,
|
||||||
)]
|
)]
|
||||||
#[strum(serialize_all = "snake_case")]
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
#[cfg_attr(feature = "backend", PgType = "InvitationStateMapping")]
|
||||||
pub enum InvitationState {
|
pub enum InvitationState {
|
||||||
|
#[default]
|
||||||
Sent,
|
Sent,
|
||||||
Accepted,
|
Accepted,
|
||||||
Revoked,
|
Revoked,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for InvitationState {
|
|
||||||
fn default() -> Self {
|
|
||||||
InvitationState::Sent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "backend", derive(DbEnum))]
|
#[cfg_attr(feature = "backend", derive(DbEnum))]
|
||||||
#[cfg_attr(feature = "backend", PgType = "TimeTrackingMapping")]
|
#[cfg_attr(feature = "backend", PgType = "TimeTrackingMapping")]
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone,
|
||||||
Copy,
|
Copy,
|
||||||
Debug,
|
Debug,
|
||||||
|
Default,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
Display,
|
Display,
|
||||||
|
EnumAsStr,
|
||||||
EnumIter,
|
EnumIter,
|
||||||
|
EnumLabel,
|
||||||
EnumString,
|
EnumString,
|
||||||
|
EnumU32,
|
||||||
Hash,
|
Hash,
|
||||||
IntoStaticStr,
|
IntoStaticStr,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -225,18 +229,14 @@ impl Default for InvitationState {
|
|||||||
Serialize,
|
Serialize,
|
||||||
)]
|
)]
|
||||||
#[strum(serialize_all = "snake_case")]
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
#[cfg_attr(feature = "backend", PgType = "TimeTrackingMapping")]
|
||||||
pub enum TimeTracking {
|
pub enum TimeTracking {
|
||||||
|
#[default]
|
||||||
Untracked,
|
Untracked,
|
||||||
Fibonacci,
|
Fibonacci,
|
||||||
Hourly,
|
Hourly,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TimeTracking {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::Untracked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize)]
|
||||||
pub struct ErrorResponse {
|
pub struct ErrorResponse {
|
||||||
pub errors: Vec<String>,
|
pub errors: Vec<String>,
|
||||||
@ -386,9 +386,13 @@ pub struct IssueAssignee {
|
|||||||
Clone,
|
Clone,
|
||||||
Copy,
|
Copy,
|
||||||
Debug,
|
Debug,
|
||||||
|
Default,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
Display,
|
Display,
|
||||||
|
EnumAsStr,
|
||||||
|
EnumLabel,
|
||||||
EnumString,
|
EnumString,
|
||||||
|
EnumU32,
|
||||||
Hash,
|
Hash,
|
||||||
IntoStaticStr,
|
IntoStaticStr,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -396,18 +400,14 @@ pub struct IssueAssignee {
|
|||||||
Serialize,
|
Serialize,
|
||||||
)]
|
)]
|
||||||
#[strum(serialize_all = "snake_case")]
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
#[cfg_attr(feature = "backend", PgType = "MessageTypeMapping")]
|
||||||
pub enum MessageType {
|
pub enum MessageType {
|
||||||
ReceivedInvitation,
|
ReceivedInvitation,
|
||||||
AssignedToIssue,
|
AssignedToIssue,
|
||||||
|
#[default]
|
||||||
Mention,
|
Mention,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MessageType {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::Mention
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "backend", derive(Queryable))]
|
#[cfg_attr(feature = "backend", derive(Queryable))]
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
pub struct Message {
|
pub struct Message {
|
||||||
@ -475,10 +475,14 @@ pub struct HighlightedCode {
|
|||||||
Clone,
|
Clone,
|
||||||
Copy,
|
Copy,
|
||||||
Debug,
|
Debug,
|
||||||
|
Default,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
Display,
|
Display,
|
||||||
|
EnumAsStr,
|
||||||
EnumIter,
|
EnumIter,
|
||||||
|
EnumLabel,
|
||||||
EnumString,
|
EnumString,
|
||||||
|
EnumU32,
|
||||||
Hash,
|
Hash,
|
||||||
IntoStaticStr,
|
IntoStaticStr,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -488,18 +492,14 @@ pub struct HighlightedCode {
|
|||||||
#[strum(serialize_all = "snake_case")]
|
#[strum(serialize_all = "snake_case")]
|
||||||
#[cfg_attr(feature = "backend", PgType = "TextEditorModeMapping")]
|
#[cfg_attr(feature = "backend", PgType = "TextEditorModeMapping")]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[cfg_attr(feature = "backend", PgType = "TextEditorModeMapping")]
|
||||||
pub enum TextEditorMode {
|
pub enum TextEditorMode {
|
||||||
|
#[default]
|
||||||
MdOnly,
|
MdOnly,
|
||||||
RteOnly,
|
RteOnly,
|
||||||
Mixed,
|
Mixed,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TextEditorMode {
|
|
||||||
fn default() -> Self {
|
|
||||||
TextEditorMode::MdOnly
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "backend", derive(Queryable))]
|
#[cfg_attr(feature = "backend", derive(Queryable))]
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
pub struct UserSetting {
|
pub struct UserSetting {
|
||||||
|
@ -9,7 +9,7 @@ license = "MPL-2.0"
|
|||||||
#license-file = "../LICENSE"
|
#license-file = "../LICENSE"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
aws-s3 = ["cloud-storage-actor"]
|
cloud-storage = ["cloud-storage-actor"]
|
||||||
local-storage = ["filesystem-actor"]
|
local-storage = ["filesystem-actor"]
|
||||||
default = ["local-storage"]
|
default = ["local-storage"]
|
||||||
|
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
use actix::Actor;
|
use actix::Actor;
|
||||||
|
use actix_web::web::Data;
|
||||||
use actix_web::{App, HttpServer};
|
use actix_web::{App, HttpServer};
|
||||||
|
use tracing::info;
|
||||||
use tracing_subscriber::util::SubscriberInitExt;
|
use tracing_subscriber::util::SubscriberInitExt;
|
||||||
|
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
@ -39,28 +41,30 @@ async fn main() -> Result<(), String> {
|
|||||||
#[cfg(feature = "local-storage")]
|
#[cfg(feature = "local-storage")]
|
||||||
let fs_addr = actix::SyncArbiter::start(
|
let fs_addr = actix::SyncArbiter::start(
|
||||||
bitque_config::fs::Configuration::read().concurrency,
|
bitque_config::fs::Configuration::read().concurrency,
|
||||||
filesystem_actor::FileSystemExecutor::default,
|
filesystem_actor::LocalStorageExecutor::default,
|
||||||
);
|
);
|
||||||
#[cfg(feature = "aws-s3")]
|
#[cfg(feature = "cloud-storage")]
|
||||||
let amazon_addr = actix::SyncArbiter::start(
|
let cloud_storage_addr = actix::SyncArbiter::start(
|
||||||
bitque_config::web::Configuration::read().concurrency,
|
bitque_config::web::Configuration::read().concurrency,
|
||||||
amazon_actor::AmazonExecutor::default,
|
cloud_storage_actor::CloudStorageExecutor::default,
|
||||||
);
|
);
|
||||||
|
|
||||||
let ws_server = websocket_actor::server::WsServer::start_default();
|
let ws_server = websocket_actor::server::WsServer::start_default();
|
||||||
|
|
||||||
|
info!("Listen at {}", web_config.bind_addr());
|
||||||
|
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
let app = App::new().wrap(actix_web::middleware::Logger::default());
|
let app = App::new().wrap(actix_web::middleware::Logger::default());
|
||||||
|
|
||||||
// data step
|
// data step
|
||||||
let app = app
|
let app = app
|
||||||
.app_data(ws_server.clone())
|
.app_data(Data::new(ws_server.clone()))
|
||||||
.app_data(db_addr.clone())
|
.app_data(Data::new(db_addr.clone()))
|
||||||
.app_data(mail_addr.clone())
|
.app_data(Data::new(mail_addr.clone()))
|
||||||
.app_data(hi_addr.clone())
|
.app_data(Data::new(hi_addr.clone()))
|
||||||
.app_data(database_actor::build_pool());
|
.app_data(Data::new(database_actor::build_pool()));
|
||||||
featured! { app, "local-storage", app.app_data(fs_addr.clone()) };
|
featured! { app, "local-storage", app.app_data(Data::new(fs_addr.clone())) };
|
||||||
featured! { app, "aws-s3", app.data(amazon_addr.clone()) };
|
featured! { app, "cloud-storage", app.app_data(Data::new(cloud_storage_addr.clone())) };
|
||||||
|
|
||||||
// services step
|
// services step
|
||||||
let app = app
|
let app = app
|
||||||
|
@ -14,15 +14,15 @@ pub enum AmazonError {
|
|||||||
Credentials,
|
Credentials,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AmazonExecutor;
|
pub struct CloudStorageExecutor;
|
||||||
|
|
||||||
impl Default for AmazonExecutor {
|
impl Default for CloudStorageExecutor {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {}
|
Self {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl actix::Actor for AmazonExecutor {
|
impl actix::Actor for CloudStorageExecutor {
|
||||||
type Context = actix::SyncContext<Self>;
|
type Context = actix::SyncContext<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ pub struct S3PutObject {
|
|||||||
pub file_name: String,
|
pub file_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl actix::Handler<S3PutObject> for AmazonExecutor {
|
impl actix::Handler<S3PutObject> for CloudStorageExecutor {
|
||||||
type Result = Result<String, AmazonError>;
|
type Result = Result<String, AmazonError>;
|
||||||
|
|
||||||
fn handle(&mut self, msg: S3PutObject, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, msg: S3PutObject, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
@ -42,12 +42,12 @@ impl actix::Handler<S3PutObject> for AmazonExecutor {
|
|||||||
mut source,
|
mut source,
|
||||||
file_name,
|
file_name,
|
||||||
} = msg;
|
} = msg;
|
||||||
bitque_config::amazon::config().set_variables();
|
bitque_config::cloud_storage::config().set_variables();
|
||||||
|
|
||||||
tokio::runtime::Runtime::new()
|
tokio::runtime::Runtime::new()
|
||||||
.expect("Failed to start amazon agent")
|
.expect("Failed to start amazon agent")
|
||||||
.block_on(async {
|
.block_on(async {
|
||||||
let s3 = bitque_config::amazon::config();
|
let s3 = bitque_config::cloud_storage::config();
|
||||||
tracing::debug!("{:?}", s3);
|
tracing::debug!("{:?}", s3);
|
||||||
|
|
||||||
let mut v: Vec<u8> = Vec::with_capacity(1024 * 1024 * 16);
|
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)
|
v.extend_from_slice(&b)
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = bitque_config::amazon::config();
|
let config = bitque_config::cloud_storage::config();
|
||||||
let bucket = s3::Bucket::new(
|
let bucket = s3::Bucket::new(
|
||||||
config.bucket.as_str(),
|
config.bucket.as_str(),
|
||||||
Region::from_str(config.region_name.as_str()).unwrap(),
|
Region::from_str(config.region_name.as_str()).unwrap(),
|
||||||
|
@ -4,7 +4,7 @@ use diesel::prelude::*;
|
|||||||
|
|
||||||
use crate::models::Issue;
|
use crate::models::Issue;
|
||||||
|
|
||||||
#[derive(derive_db_execute::Execute, Default)]
|
#[derive(Default, derive_db_execute::Execute)]
|
||||||
#[db_exec(
|
#[db_exec(
|
||||||
result = "Issue",
|
result = "Issue",
|
||||||
schema = "issues",
|
schema = "issues",
|
||||||
@ -24,7 +24,7 @@ pub struct LoadProjectIssues {
|
|||||||
pub project_id: ProjectId,
|
pub project_id: ProjectId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(derive_db_execute::Execute, Default)]
|
#[derive(Default, derive_db_execute::Execute)]
|
||||||
#[db_exec(result = "Issue", schema = "issues")]
|
#[db_exec(result = "Issue", schema = "issues")]
|
||||||
pub struct UpdateIssue {
|
pub struct UpdateIssue {
|
||||||
pub issue_id: bitque_data::IssueId,
|
pub issue_id: bitque_data::IssueId,
|
||||||
|
@ -2,12 +2,11 @@ extern crate proc_macro;
|
|||||||
|
|
||||||
use proc_macro::{TokenStream, TokenTree};
|
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!(
|
let mut code = format!(
|
||||||
r#"
|
r#"
|
||||||
#[cfg(feature = "frontend")]
|
|
||||||
impl {name} {{
|
impl {name} {{
|
||||||
pub fn to_str(&self) -> &'static str {{
|
pub fn as_str(&self) -> &'static str {{
|
||||||
match self {{
|
match self {{
|
||||||
"#,
|
"#,
|
||||||
name = name,
|
name = name,
|
||||||
@ -32,8 +31,7 @@ impl {name} {{
|
|||||||
fn from_str(name: &str, variants: &[String]) -> String {
|
fn from_str(name: &str, variants: &[String]) -> String {
|
||||||
let mut code = format!(
|
let mut code = format!(
|
||||||
r#"
|
r#"
|
||||||
#[cfg(feature = "frontend")]
|
impl std::str::FromStr for {name} {{
|
||||||
impl FromStr for {name} {{
|
|
||||||
type Err = String;
|
type Err = String;
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {{
|
fn from_str(s: &str) -> Result<Self, Self::Err> {{
|
||||||
match s {{
|
match s {{
|
||||||
@ -68,7 +66,6 @@ impl FromStr for {name} {{
|
|||||||
fn into_label(name: &str, variants: &[String]) -> String {
|
fn into_label(name: &str, variants: &[String]) -> String {
|
||||||
let mut code = format!(
|
let mut code = format!(
|
||||||
r#"
|
r#"
|
||||||
#[cfg(feature = "frontend")]
|
|
||||||
impl {name} {{
|
impl {name} {{
|
||||||
pub fn to_label(&self) -> &'static str {{
|
pub fn to_label(&self) -> &'static str {{
|
||||||
match self {{
|
match self {{
|
||||||
@ -139,16 +136,128 @@ impl Into<{name}> for u32 {{
|
|||||||
code
|
code
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_derive(EnumPrimitive)]
|
#[proc_macro_derive(EnumU32)]
|
||||||
pub fn derive_enum_primitive(item: TokenStream) -> TokenStream {
|
pub fn derive_enum_u32(item: TokenStream) -> TokenStream {
|
||||||
let mut it = item.into_iter().peekable();
|
let mut it = item.into_iter().peekable();
|
||||||
|
|
||||||
while let Some(token) = it.peek() {
|
while let Some(token) = it.peek() {
|
||||||
if let TokenTree::Ident(_) = token {
|
match token {
|
||||||
break;
|
TokenTree::Ident(_) => {
|
||||||
} else {
|
break;
|
||||||
it.next();
|
}
|
||||||
|
_ => {
|
||||||
|
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 let Some(TokenTree::Ident(ident)) = it.next() {
|
||||||
if ident.to_string().as_str() != "pub" {
|
if ident.to_string().as_str() != "pub" {
|
||||||
panic!("Expect to find keyword pub but was found {:?}", ident)
|
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();
|
let mut code = String::new();
|
||||||
|
|
||||||
code.push_str(from_str(&name, &variants).as_str());
|
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.parse().unwrap()
|
||||||
code.push_str(into_u32(&name, &variants).as_str());
|
}
|
||||||
code.push_str(from_u32(&name, &variants).as_str());
|
|
||||||
|
#[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()
|
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
|
/// Defines the casing for the database representation. Follows serde naming
|
||||||
/// convention.
|
/// convention.
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
enum CaseStyle {
|
enum CaseStyle {
|
||||||
Camel,
|
Camel,
|
||||||
Kebab,
|
Kebab,
|
||||||
|
@ -13,11 +13,11 @@ pub enum FsError {
|
|||||||
WriteFile,
|
WriteFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FileSystemExecutor {
|
pub struct LocalStorageExecutor {
|
||||||
config: Configuration,
|
config: Configuration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileSystemExecutor {
|
impl LocalStorageExecutor {
|
||||||
pub fn client_path(&self) -> &str {
|
pub fn client_path(&self) -> &str {
|
||||||
self.config.client_path.as_str()
|
self.config.client_path.as_str()
|
||||||
}
|
}
|
||||||
@ -27,7 +27,7 @@ impl FileSystemExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FileSystemExecutor {
|
impl Default for LocalStorageExecutor {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
config: Configuration::read(),
|
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>;
|
type Context = SyncContext<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ pub struct CreateFile {
|
|||||||
pub file_name: String,
|
pub file_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl actix::Handler<CreateFile> for FileSystemExecutor {
|
impl actix::Handler<CreateFile> for LocalStorageExecutor {
|
||||||
type Result = Result<usize, FsError>;
|
type Result = Result<usize, FsError>;
|
||||||
|
|
||||||
fn handle(&mut self, msg: CreateFile, _ctx: &mut Self::Context) -> Self::Result {
|
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
|
.theme_set
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.themes
|
.themes
|
||||||
.get("GitHub")
|
.get("InspiredGitHub")
|
||||||
.ok_or(HighlightError::UnknownTheme)?;
|
.ok_or(HighlightError::UnknownTheme)?;
|
||||||
|
|
||||||
let mut hi = HighlightLines::new(set, theme);
|
let mut hi = HighlightLines::new(set, theme);
|
||||||
|
@ -1,24 +1,12 @@
|
|||||||
use std::io::BufRead;
|
use syntect::highlighting::ThemeSet;
|
||||||
|
use syntect::parsing::SyntaxSet;
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn integrated_syntaxset() -> syntect::parsing::SyntaxSet {
|
pub fn integrated_syntaxset() -> syntect::parsing::SyntaxSet {
|
||||||
from_binary(include_bytes!("./syntaxes.bin"))
|
SyntaxSet::load_defaults_newlines()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn integrated_themeset() -> syntect::highlighting::ThemeSet {
|
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]
|
[features]
|
||||||
local-storage = ["filesystem-actor"]
|
local-storage = ["filesystem-actor"]
|
||||||
aws-s3 = ["cloud-storage-actor"]
|
cloud-storage = ["cloud-storage-actor"]
|
||||||
default = ["local-storage"]
|
default = ["local-storage"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -4,29 +4,28 @@ use actix::Addr;
|
|||||||
use actix_multipart::{Field, Multipart};
|
use actix_multipart::{Field, Multipart};
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use actix_web::{post, web, Error, HttpResponse};
|
use actix_web::{post, web, Error, HttpResponse};
|
||||||
use bitque_data::msg::{WsMsg, WsMsgUser};
|
use bitque_data::msg::WsMsgUser;
|
||||||
use bitque_data::{User, UserId};
|
use bitque_data::{User, UserId};
|
||||||
use database_actor::authorize_user::AuthorizeUser;
|
use database_actor::authorize_user::AuthorizeUser;
|
||||||
use database_actor::user_projects::CurrentUserProject;
|
use database_actor::user_projects::CurrentUserProject;
|
||||||
use database_actor::users::UpdateAvatarUrl;
|
use database_actor::users::UpdateAvatarUrl;
|
||||||
use database_actor::DbExecutor;
|
use database_actor::DbExecutor;
|
||||||
#[cfg(feature = "local-storage")]
|
|
||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
use futures::{StreamExt, TryStreamExt};
|
use futures::{StreamExt, TryStreamExt};
|
||||||
use tracing::error;
|
use tracing::{error, warn};
|
||||||
use websocket_actor::server::InnerMsg::BroadcastToChannel;
|
use websocket_actor::server::InnerMsg::BroadcastToChannel;
|
||||||
use websocket_actor::server::WsServer;
|
use websocket_actor::server::WsServer;
|
||||||
|
|
||||||
use crate::ServiceError;
|
use crate::ServiceError;
|
||||||
|
|
||||||
#[cfg(feature = "aws-s3")]
|
#[cfg(feature = "cloud-storage")]
|
||||||
#[post("/")]
|
#[post("/")]
|
||||||
pub async fn upload(
|
pub async fn upload(
|
||||||
mut payload: Multipart,
|
mut payload: Multipart,
|
||||||
db: Data<Addr<DbExecutor>>,
|
db: Data<Addr<DbExecutor>>,
|
||||||
ws: Data<Addr<WsServer>>,
|
ws: Data<Addr<WsServer>>,
|
||||||
fs: Data<Addr<filesystem_actor::FileSystemExecutor>>,
|
fs: Data<Addr<filesystem_actor::LocalStorageExecutor>>,
|
||||||
amazon: Data<Addr<amazon_actor::AmazonExecutor>>,
|
cloud_storage: Data<Addr<cloud_storage_actor::CloudStorageExecutor>>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let mut user_id: Option<UserId> = None;
|
let mut user_id: Option<UserId> = None;
|
||||||
let mut avatar_url: Option<String> = 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?);
|
user_id = Some(handle_token(field, db.clone()).await?);
|
||||||
}
|
}
|
||||||
Some("avatar") => {
|
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(
|
avatar_url = Some(
|
||||||
crate::handlers::upload_avatar_image::handle_image(
|
crate::handlers::upload_avatar_image::handle_image(
|
||||||
id,
|
id,
|
||||||
field,
|
field,
|
||||||
disposition.clone(),
|
|
||||||
fs.clone(),
|
fs.clone(),
|
||||||
amazon.clone(),
|
cloud_storage.clone(),
|
||||||
)
|
)
|
||||||
.await?,
|
.await?,
|
||||||
);
|
);
|
||||||
@ -56,6 +57,10 @@ pub async fn upload(
|
|||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tracing::info!("user_id {user_id:?}");
|
||||||
|
tracing::info!("token {avatar_url:?}");
|
||||||
|
|
||||||
let user_id = match user_id {
|
let user_id = match user_id {
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
_ => return Ok(HttpResponse::Unauthorized().finish()),
|
_ => return Ok(HttpResponse::Unauthorized().finish()),
|
||||||
@ -69,25 +74,26 @@ pub async fn upload(
|
|||||||
match (user_id, avatar_url) {
|
match (user_id, avatar_url) {
|
||||||
(user_id, Some(avatar_url)) => {
|
(user_id, Some(avatar_url)) => {
|
||||||
let user = update_user_avatar(user_id, avatar_url.clone(), db).await?;
|
let user = update_user_avatar(user_id, avatar_url.clone(), db).await?;
|
||||||
ws.send(BroadcastToChannel(
|
let Ok(_) = ws.send(BroadcastToChannel(
|
||||||
project_id,
|
project_id,
|
||||||
WsMsgUser::AvatarUrlChanged(user.id, avatar_url).into(),
|
WsMsgUser::AvatarUrlChanged(user.id, avatar_url).into(),
|
||||||
))
|
))
|
||||||
.await
|
.await else {
|
||||||
.map_err(|_| HttpResponse::UnprocessableEntity().finish())?;
|
return Ok(HttpResponse::UnprocessableEntity().finish());
|
||||||
|
};
|
||||||
Ok(HttpResponse::NoContent().finish())
|
Ok(HttpResponse::NoContent().finish())
|
||||||
}
|
}
|
||||||
_ => Ok(HttpResponse::UnprocessableEntity().finish()),
|
_ => Ok(HttpResponse::UnprocessableEntity().finish()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "aws-s3"))]
|
#[cfg(not(feature = "cloud-storage"))]
|
||||||
#[post("/")]
|
#[post("/")]
|
||||||
pub async fn upload(
|
pub async fn upload(
|
||||||
mut payload: Multipart,
|
mut payload: Multipart,
|
||||||
db: Data<Addr<DbExecutor>>,
|
db: Data<Addr<DbExecutor>>,
|
||||||
ws: Data<Addr<WsServer>>,
|
ws: Data<Addr<WsServer>>,
|
||||||
fs: Data<Addr<filesystem_actor::FileSystemExecutor>>,
|
fs: Data<Addr<filesystem_actor::LocalStorageExecutor>>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let mut user_id: Option<UserId> = None;
|
let mut user_id: Option<UserId> = None;
|
||||||
let mut avatar_url: Option<String> = None;
|
let mut avatar_url: Option<String> = None;
|
||||||
@ -144,7 +150,7 @@ async fn update_user_avatar(
|
|||||||
user_id: UserId,
|
user_id: UserId,
|
||||||
new_url: String,
|
new_url: String,
|
||||||
db: Data<Addr<DbExecutor>>,
|
db: Data<Addr<DbExecutor>>,
|
||||||
) -> Result<User, actix_web::Error> {
|
) -> Result<User, Error> {
|
||||||
match db
|
match db
|
||||||
.send(UpdateAvatarUrl {
|
.send(UpdateAvatarUrl {
|
||||||
user_id,
|
user_id,
|
||||||
@ -155,11 +161,11 @@ async fn update_user_avatar(
|
|||||||
Ok(Ok(user)) => Ok(user),
|
Ok(Ok(user)) => Ok(user),
|
||||||
|
|
||||||
Ok(Err(e)) => {
|
Ok(Err(e)) => {
|
||||||
::tracing::error!("{:?}", e);
|
error!("{:?}", e);
|
||||||
Err(ServiceError::Unauthorized.into())
|
Err(ServiceError::Unauthorized.into())
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
::tracing::error!("{:?}", e);
|
error!("{:?}", e);
|
||||||
Err(ServiceError::Unauthorized.into())
|
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(Ok(user)) => Ok(user.id),
|
||||||
|
|
||||||
Ok(Err(e)) => {
|
Ok(Err(e)) => {
|
||||||
::tracing::error!("{:?}", e);
|
error!("{:?}", e);
|
||||||
Err(ServiceError::Unauthorized.into())
|
Err(ServiceError::Unauthorized.into())
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
::tracing::error!("{:?}", e);
|
error!("{:?}", e);
|
||||||
Err(ServiceError::Unauthorized.into())
|
Err(ServiceError::Unauthorized.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,14 @@ use bitque_data::ErrorResponse;
|
|||||||
const TOKEN_NOT_FOUND: &str = "Token not found";
|
const TOKEN_NOT_FOUND: &str = "Token not found";
|
||||||
const DATABASE_CONNECTION_FAILED: &str = "Database connection failed";
|
const DATABASE_CONNECTION_FAILED: &str = "Database connection failed";
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum HighlightError {
|
pub enum HighlightError {
|
||||||
UnknownLanguage,
|
UnknownLanguage,
|
||||||
UnknownTheme,
|
UnknownTheme,
|
||||||
ResultUnserializable,
|
ResultUnserializable,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ServiceError {
|
pub enum ServiceError {
|
||||||
Unauthorized,
|
Unauthorized,
|
||||||
DatabaseConnectionLost,
|
DatabaseConnectionLost,
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
use actix::Addr;
|
use actix::{spawn, Addr};
|
||||||
use actix_multipart::Field;
|
use actix_multipart::Field;
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use actix_web::Error;
|
use actix_web::{Error, HttpResponse};
|
||||||
use bitque_data::UserId;
|
use bitque_data::UserId;
|
||||||
|
use futures::future::join_all;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use tokio::sync::broadcast::{Receiver, Sender};
|
use tokio::sync::broadcast::{Receiver, Sender};
|
||||||
use tracing::error;
|
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(
|
pub(crate) async fn handle_image(
|
||||||
user_id: UserId,
|
user_id: UserId,
|
||||||
mut field: Field,
|
mut field: Field,
|
||||||
fs: Data<Addr<filesystem_actor::FileSystemExecutor>>,
|
fs: Data<Addr<filesystem_actor::LocalStorageExecutor>>,
|
||||||
amazon: Data<Addr<amazon_actor::AmazonExecutor>>,
|
cloud_storage: Data<Addr<cloud_storage_actor::CloudStorageExecutor>>,
|
||||||
) -> Result<String, Error> {
|
) -> Result<String, Error> {
|
||||||
let filename = field.content_disposition().get_filename().unwrap();
|
let filename = field.content_disposition().get_filename().unwrap();
|
||||||
let system_file_name = format!("{}-{}", user_id, filename);
|
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 (sender, receiver) = tokio::sync::broadcast::channel(64);
|
||||||
|
|
||||||
let fs_fut = local_storage_write(system_file_name.clone(), fs, user_id, sender.subscribe());
|
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 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;
|
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 {
|
for res in results {
|
||||||
new_link = url;
|
return if let Ok(Some(link)) = res {
|
||||||
|
Ok(link)
|
||||||
|
} else {
|
||||||
|
Err(HttpResponse::UnprocessableEntity().finish().into())
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
Err(HttpResponse::UnprocessableEntity().finish().into())
|
||||||
if let Ok(url) = aws_join.await {
|
|
||||||
new_link = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(new_link.unwrap_or_default())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(not(feature = "local-storage"), feature = "aws-s3"))]
|
#[cfg(all(not(feature = "local-storage"), feature = "cloud-storage"))]
|
||||||
pub(crate) async fn handle_image(
|
pub(crate) async fn handle_image(
|
||||||
user_id: UserId,
|
user_id: UserId,
|
||||||
mut field: Field,
|
mut field: Field,
|
||||||
amazon: Data<Addr<amazon_actor::AmazonExecutor>>,
|
cloud_storage: Data<Addr<cloud_storage_actor::CloudStorageExecutor>>,
|
||||||
) -> Result<String, Error> {
|
) -> Result<String, Error> {
|
||||||
let filename = field.content_disposition().get_filename().unwrap();
|
let filename = field.content_disposition().get_filename().unwrap();
|
||||||
let system_file_name = format!("{}-{}", user_id, filename);
|
let system_file_name = format!("{}-{}", user_id, filename);
|
||||||
|
|
||||||
let (sender, receiver) = tokio::sync::broadcast::channel(64);
|
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 read_fut = read_form_data(&mut field, sender);
|
||||||
|
|
||||||
let aws_join = tokio::task::spawn(aws_fut);
|
let aws_join = tokio::task::spawn(aws_fut);
|
||||||
@ -66,11 +64,11 @@ pub(crate) async fn handle_image(
|
|||||||
Ok(new_link.unwrap_or_default())
|
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(
|
pub(crate) async fn handle_image(
|
||||||
user_id: UserId,
|
user_id: UserId,
|
||||||
mut field: Field,
|
mut field: Field,
|
||||||
fs: Data<Addr<filesystem_actor::FileSystemExecutor>>,
|
fs: Data<Addr<filesystem_actor::LocalStorageExecutor>>,
|
||||||
) -> Result<String, Error> {
|
) -> Result<String, Error> {
|
||||||
let filename = field.content_disposition().get_filename().unwrap();
|
let filename = field.content_disposition().get_filename().unwrap();
|
||||||
let system_file_name = format!("{}-{}", user_id, filename);
|
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
|
/// Stream bytes directly to AWS S3 Service
|
||||||
#[cfg(feature = "aws-s3")]
|
#[cfg(feature = "cloud-storage")]
|
||||||
async fn aws_s3(
|
async fn cloud_storage_write(
|
||||||
system_file_name: String,
|
system_file_name: String,
|
||||||
amazon: Data<Addr<amazon_actor::AmazonExecutor>>,
|
cloud_storage: Data<Addr<cloud_storage_actor::CloudStorageExecutor>>,
|
||||||
receiver: Receiver<bytes::Bytes>,
|
receiver: Receiver<bytes::Bytes>,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
let s3 = bitque_config::amazon::config();
|
let s3 = bitque_config::cloud_storage::config();
|
||||||
if !s3.active {
|
if !s3.active {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
match amazon
|
match cloud_storage
|
||||||
.send(amazon_actor::S3PutObject {
|
.send(cloud_storage_actor::S3PutObject {
|
||||||
source: receiver,
|
source: receiver,
|
||||||
file_name: system_file_name.to_string(),
|
file_name: system_file_name.to_string(),
|
||||||
})
|
})
|
||||||
@ -129,7 +127,7 @@ async fn aws_s3(
|
|||||||
#[cfg(feature = "local-storage")]
|
#[cfg(feature = "local-storage")]
|
||||||
async fn local_storage_write(
|
async fn local_storage_write(
|
||||||
system_file_name: String,
|
system_file_name: String,
|
||||||
fs: Data<Addr<filesystem_actor::FileSystemExecutor>>,
|
fs: Data<Addr<filesystem_actor::LocalStorageExecutor>>,
|
||||||
_user_id: bitque_data::UserId,
|
_user_id: bitque_data::UserId,
|
||||||
receiver: Receiver<bytes::Bytes>,
|
receiver: Receiver<bytes::Bytes>,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
|
@ -8,11 +8,6 @@ repository = "https://gitlab.com/adrian.wozniak/bitque"
|
|||||||
license = "MPL-2.0"
|
license = "MPL-2.0"
|
||||||
#license-file = "../LICENSE"
|
#license-file = "../LICENSE"
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["cdylib", "rlib"]
|
|
||||||
name = "bitque_client"
|
|
||||||
path = "src/lib.rs"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
print-model = []
|
print-model = []
|
||||||
default = []
|
default = []
|
||||||
@ -25,16 +20,20 @@ console_error_panic_hook = { version = "*" }
|
|||||||
derive_enum_iter = { workspace = true }
|
derive_enum_iter = { workspace = true }
|
||||||
derive_enum_primitive = { workspace = true }
|
derive_enum_primitive = { workspace = true }
|
||||||
dotenv = { version = "*" }
|
dotenv = { version = "*" }
|
||||||
futures = "0.3.6"
|
futures = { version = "0.3.6" }
|
||||||
js-sys = { version = "*", default-features = false }
|
js-sys = { version = "*", default-features = false }
|
||||||
seed = { version = "0" }
|
seed = { version = "0", features = ['serde-wasm-bindgen'] }
|
||||||
serde = { version = "1", features = [] }
|
serde = { version = "1", features = ['derive'] }
|
||||||
serde_json = { version = "*" }
|
serde_json = { version = "*" }
|
||||||
tracing = { version = "0.1.37" }
|
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"] }
|
uuid = { version = "1.3.0", features = ["serde"] }
|
||||||
wasm-bindgen = { version = "*", features = ["enable-interning"] }
|
wasm-bindgen = { version = "*", features = ["enable-interning"] }
|
||||||
wasm-bindgen-futures = { version = "*" }
|
wasm-bindgen-futures = { version = "*" }
|
||||||
wee_alloc = { version = "*", features = ["static_array_backend"] }
|
wee_alloc = { version = "*", features = ["static_array_backend"] }
|
||||||
|
wasm-sockets = { version = "1", features = [] }
|
||||||
|
strum = { version = "*" }
|
||||||
|
|
||||||
[dependencies.web-sys]
|
[dependencies.web-sys]
|
||||||
version = "*"
|
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 |