Compare commits
2 Commits
2393d81a3f
..
v0.1.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 37d2b66c56 | |||
| 95b44f1e55 |
Generated
+405
-4
@@ -8,6 +8,12 @@ version = "2.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler32"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aead"
|
name = "aead"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
@@ -279,6 +285,7 @@ dependencies = [
|
|||||||
"matchit",
|
"matchit",
|
||||||
"memchr",
|
"memchr",
|
||||||
"mime",
|
"mime",
|
||||||
|
"multer",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
@@ -348,6 +355,26 @@ version = "1.8.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
|
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bincode"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740"
|
||||||
|
dependencies = [
|
||||||
|
"bincode_derive",
|
||||||
|
"serde",
|
||||||
|
"unty",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bincode_derive"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09"
|
||||||
|
dependencies = [
|
||||||
|
"virtue",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
@@ -441,6 +468,25 @@ dependencies = [
|
|||||||
"rustversion",
|
"rustversion",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cbindgen"
|
||||||
|
version = "0.29.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "befbfd072a8e81c02f8c507aefce431fe5e7d051f83d48a23ffc9b9fe5a11799"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"heck 0.5.0",
|
||||||
|
"indexmap 2.13.0",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"syn 2.0.117",
|
||||||
|
"tempfile",
|
||||||
|
"toml",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.57"
|
version = "1.2.57"
|
||||||
@@ -448,9 +494,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423"
|
checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"find-msvc-tools",
|
"find-msvc-tools",
|
||||||
|
"jobserver",
|
||||||
|
"libc",
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cedarwood"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d910bedd62c24733263d0bed247460853c9d22e8956bd4cd964302095e04e90"
|
||||||
|
dependencies = [
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@@ -608,6 +665,15 @@ version = "0.8.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core2"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
@@ -823,6 +889,12 @@ dependencies = [
|
|||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dary_heap"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06d2e3287df1c007e74221c49ca10a95d557349e54b3a75dc2fb14712c751f04"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "data-encoding"
|
name = "data-encoding"
|
||||||
version = "2.10.0"
|
version = "2.10.0"
|
||||||
@@ -1057,6 +1129,37 @@ version = "2.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ferrous-opencc"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "800f9a39ad26b200b08673c059c2dbf78d1f63901a873e9ac425ba471e690410"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bincode",
|
||||||
|
"cbindgen",
|
||||||
|
"ferrous-opencc-compiler",
|
||||||
|
"fst",
|
||||||
|
"phf",
|
||||||
|
"phf_codegen",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
"zstd",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ferrous-opencc-compiler"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ed87f42a19a234e791d6e769928819382c3d210da2c9049f832a1ae772d7082"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bincode",
|
||||||
|
"fst",
|
||||||
|
"zstd",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.27"
|
version = "0.2.27"
|
||||||
@@ -1107,6 +1210,12 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foreign-types"
|
name = "foreign-types"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
@@ -1140,6 +1249,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fst"
|
||||||
|
version = "0.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "funty"
|
name = "funty"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
@@ -1338,7 +1453,7 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"foldhash",
|
"foldhash 0.1.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1346,6 +1461,11 @@ name = "hashbrown"
|
|||||||
version = "0.16.1"
|
version = "0.16.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||||
|
dependencies = [
|
||||||
|
"allocator-api2",
|
||||||
|
"equivalent",
|
||||||
|
"foldhash 0.2.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashlink"
|
name = "hashlink"
|
||||||
@@ -1698,6 +1818,39 @@ dependencies = [
|
|||||||
"icu_properties",
|
"icu_properties",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "include-flate"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a05fb00d9abc625268e0573a519506b264a7d6965de09bac13201bfb44e723d"
|
||||||
|
dependencies = [
|
||||||
|
"include-flate-codegen",
|
||||||
|
"include-flate-compress",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "include-flate-codegen"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92c3c319a7527668538a8530c541e74e881e94c4f41e1425622d0a41c16468af"
|
||||||
|
dependencies = [
|
||||||
|
"include-flate-compress",
|
||||||
|
"proc-macro-error2",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "include-flate-compress"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed0bd9ea81b94169d61c5a397e9faef02153d3711fc62d3270bcde3ac85380d9"
|
||||||
|
dependencies = [
|
||||||
|
"libflate",
|
||||||
|
"zstd",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.9.3"
|
version = "1.9.3"
|
||||||
@@ -1829,6 +1982,29 @@ version = "1.0.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
|
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jieba-macros"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "348294e44ee7e3c42685da656490f8febc7359632544019621588902216da95c"
|
||||||
|
dependencies = [
|
||||||
|
"phf_codegen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jieba-rs"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "766bd7012aa5ba49411ebdf4e93bddd59b182d2918e085d58dec5bb9b54b7105"
|
||||||
|
dependencies = [
|
||||||
|
"cedarwood",
|
||||||
|
"include-flate",
|
||||||
|
"jieba-macros",
|
||||||
|
"phf",
|
||||||
|
"regex",
|
||||||
|
"rustc-hash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jiff"
|
name = "jiff"
|
||||||
version = "0.2.23"
|
version = "0.2.23"
|
||||||
@@ -1853,6 +2029,16 @@ dependencies = [
|
|||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jobserver"
|
||||||
|
version = "0.1.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.3.4",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.91"
|
version = "0.3.91"
|
||||||
@@ -1904,6 +2090,30 @@ version = "0.2.183"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
|
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libflate"
|
||||||
|
version = "2.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3248b8d211bd23a104a42d81b4fa8bb8ac4a3b75e7a43d85d2c9ccb6179cd74"
|
||||||
|
dependencies = [
|
||||||
|
"adler32",
|
||||||
|
"core2",
|
||||||
|
"crc32fast",
|
||||||
|
"dary_heap",
|
||||||
|
"libflate_lz77",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libflate_lz77"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a599cb10a9cd92b1300debcef28da8f70b935ec937f44fcd1b70a7c986a11c5c"
|
||||||
|
dependencies = [
|
||||||
|
"core2",
|
||||||
|
"hashbrown 0.16.1",
|
||||||
|
"rle-decode-fast",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
@@ -2116,8 +2326,10 @@ dependencies = [
|
|||||||
"crossterm",
|
"crossterm",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"ferrous-opencc",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"hex",
|
"hex",
|
||||||
|
"jieba-rs",
|
||||||
"libc",
|
"libc",
|
||||||
"md5",
|
"md5",
|
||||||
"moka",
|
"moka",
|
||||||
@@ -2190,6 +2402,23 @@ dependencies = [
|
|||||||
"webpki-roots 0.25.4",
|
"webpki-roots 0.25.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "multer"
|
||||||
|
version = "3.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"encoding_rs",
|
||||||
|
"futures-util",
|
||||||
|
"http",
|
||||||
|
"httparse",
|
||||||
|
"memchr",
|
||||||
|
"mime",
|
||||||
|
"spin",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "native-tls"
|
name = "native-tls"
|
||||||
version = "0.2.18"
|
version = "0.2.18"
|
||||||
@@ -2440,6 +2669,59 @@ version = "2.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf"
|
||||||
|
dependencies = [
|
||||||
|
"phf_macros",
|
||||||
|
"phf_shared",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_codegen"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1"
|
||||||
|
dependencies = [
|
||||||
|
"phf_generator",
|
||||||
|
"phf_shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_generator"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737"
|
||||||
|
dependencies = [
|
||||||
|
"fastrand",
|
||||||
|
"phf_shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_macros"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef"
|
||||||
|
dependencies = [
|
||||||
|
"phf_generator",
|
||||||
|
"phf_shared",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_shared"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266"
|
||||||
|
dependencies = [
|
||||||
|
"siphasher",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.1.11"
|
version = "1.1.11"
|
||||||
@@ -2599,6 +2881,28 @@ dependencies = [
|
|||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error-attr2"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error2"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error-attr2",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.106"
|
version = "1.0.106"
|
||||||
@@ -2966,6 +3270,12 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rle-decode-fast"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rsa"
|
name = "rsa"
|
||||||
version = "0.9.10"
|
version = "0.9.10"
|
||||||
@@ -3323,6 +3633,15 @@ dependencies = [
|
|||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "876ac351060d4f882bb1032b6369eb0aef79ad9df1ea8bc404874d8cc3d0cd98"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_urlencoded"
|
name = "serde_urlencoded"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@@ -3458,6 +3777,12 @@ version = "0.3.8"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
|
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "siphasher"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
@@ -4059,6 +4384,30 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.9.12+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap 2.13.0",
|
||||||
|
"serde_core",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime 0.7.5+spec-1.1.0",
|
||||||
|
"toml_parser",
|
||||||
|
"toml_writer",
|
||||||
|
"winnow 0.7.15",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.7.5+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "1.0.1+spec-1.1.0"
|
version = "1.0.1+spec-1.1.0"
|
||||||
@@ -4075,9 +4424,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "8ca1a40644a28bce036923f6a431df0b34236949d111cc07cb6dca830c9ef2e1"
|
checksum = "8ca1a40644a28bce036923f6a431df0b34236949d111cc07cb6dca830c9ef2e1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap 2.13.0",
|
"indexmap 2.13.0",
|
||||||
"toml_datetime",
|
"toml_datetime 1.0.1+spec-1.1.0",
|
||||||
"toml_parser",
|
"toml_parser",
|
||||||
"winnow",
|
"winnow 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4086,9 +4435,15 @@ version = "1.0.10+spec-1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420"
|
checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winnow",
|
"winnow 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_writer"
|
||||||
|
version = "1.1.0+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d282ade6016312faf3e41e57ebbba0c073e4056dab1232ab1cb624199648f8ed"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tonic"
|
name = "tonic"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
@@ -4393,6 +4748,12 @@ version = "0.9.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unty"
|
||||||
|
version = "0.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.5.8"
|
version = "2.5.8"
|
||||||
@@ -4491,6 +4852,12 @@ version = "0.9.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "virtue"
|
||||||
|
version = "0.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@@ -5029,6 +5396,12 @@ version = "0.53.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.7.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@@ -5281,3 +5654,31 @@ name = "zmij"
|
|||||||
version = "1.0.21"
|
version = "1.0.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd"
|
||||||
|
version = "0.13.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a"
|
||||||
|
dependencies = [
|
||||||
|
"zstd-safe",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd-safe"
|
||||||
|
version = "7.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d"
|
||||||
|
dependencies = [
|
||||||
|
"zstd-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd-sys"
|
||||||
|
version = "2.0.16+zstd.1.5.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|||||||
+17
-5
@@ -33,10 +33,14 @@ sha2 = "0.10"
|
|||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
uuid = { version = "1.0", features = ["v4"] }
|
uuid = { version = "1.0", features = ["v4"] }
|
||||||
|
|
||||||
# Security
|
# Security
|
||||||
subtle = "2.5"
|
subtle = "2.5"
|
||||||
aes-gcm = "0.10"
|
aes-gcm = "0.10"
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
|
|
||||||
|
# Text processing
|
||||||
|
jieba-rs = "0.8.1"
|
||||||
|
ferrous-opencc = { version = "0.3.1", features = ["s2t-conversion", "t2s-conversion"] }
|
||||||
|
|
||||||
# Cache
|
# Cache
|
||||||
moka = { version = "0.12", features = ["future"] }
|
moka = { version = "0.12", features = ["future"] }
|
||||||
@@ -50,7 +54,7 @@ qdrant-client = "1.7"
|
|||||||
reqwest = { version = "0.12", features = ["json"] }
|
reqwest = { version = "0.12", features = ["json"] }
|
||||||
|
|
||||||
# HTTP Server
|
# HTTP Server
|
||||||
axum = "0.7"
|
axum = { version = "0.7", features = ["multipart"] }
|
||||||
tower = "0.4"
|
tower = "0.4"
|
||||||
|
|
||||||
# API Documentation
|
# API Documentation
|
||||||
@@ -98,3 +102,11 @@ path = "src/playground.rs"
|
|||||||
[[bin]]
|
[[bin]]
|
||||||
name = "fix_chunks"
|
name = "fix_chunks"
|
||||||
path = "src/bin/fix_chunks.rs"
|
path = "src/bin/fix_chunks.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "migrate_chinese_text"
|
||||||
|
path = "src/bin/migrate_chinese_text.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "test_bm25_simple"
|
||||||
|
path = "src/bin/test_bm25_simple.rs"
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ check_backup_status() {
|
|||||||
if [ -d "$service_backup_dir" ]; then
|
if [ -d "$service_backup_dir" ]; then
|
||||||
file_count=$(find "$service_backup_dir" -type f 2>/dev/null | wc -l)
|
file_count=$(find "$service_backup_dir" -type f 2>/dev/null | wc -l)
|
||||||
size=$(du -sb "$service_backup_dir" 2>/dev/null | cut -f1)
|
size=$(du -sb "$service_backup_dir" 2>/dev/null | cut -f1)
|
||||||
latest_file=$(find "$service_backup_dir" -type f \( -name "*.tar.gz" -o -name "*.sql.gz" -o -name "*.rdb" \) 2>/dev/null | head -1)
|
latest_file=$(find "$service_backup_dir" -type f \( -name "*.tar.gz" -o -name "*.sql.gz" -o -name "*.rdb" \) -printf "%T@ %p\n" 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
|
||||||
|
|
||||||
# 處理 size 為空或 0 的情況
|
# 處理 size 為空或 0 的情況
|
||||||
if [ -z "$size" ] || [ "$size" = "0" ]; then
|
if [ -z "$size" ] || [ "$size" = "0" ]; then
|
||||||
@@ -271,12 +271,12 @@ tier_backups() {
|
|||||||
|
|
||||||
# 7天前: daily -> weekly
|
# 7天前: daily -> weekly
|
||||||
# 命名格式: {service}_{type}_{YYYYMMDD}_{HHMMSS}.{ext}
|
# 命名格式: {service}_{type}_{YYYYMMDD}_{HHMMSS}.{ext}
|
||||||
find "$BACKUP_BASE/daily" -type f -mtime +7 | while read -r file; do
|
find "$BACKUP_BASE/daily" -type f -mtime +6 | while read -r file; do
|
||||||
service=$(basename "$(dirname "$file")")
|
service=$(basename "$(dirname "$file")")
|
||||||
|
|
||||||
# 解析時間戳
|
# 解析時間戳
|
||||||
filename=$(basename "$file")
|
filename=$(basename "$file")
|
||||||
timestamp=$(echo "$filename" | grep -oP '\d{8}_\d{6}' || echo "")
|
timestamp=$(echo "$filename" | grep -oE '[0-9]{8}_[0-9]{6}' || echo "")
|
||||||
|
|
||||||
if [ -n "$timestamp" ]; then
|
if [ -n "$timestamp" ]; then
|
||||||
year=${timestamp:0:4}
|
year=${timestamp:0:4}
|
||||||
|
|||||||
Executable
+821
@@ -0,0 +1,821 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
export PATH="/usr/local/bin:/opt/homebrew/bin:/opt/homebrew/opt/postgresql@18/bin:/usr/bin:/bin:/sbin:/opt/homebrew/opt/mysql-client/bin:$PATH"
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
# Momentry 統一備份腳本
|
||||||
|
# 路徑: /Users/accusys/momentry/scripts/backup_all.sh
|
||||||
|
#
|
||||||
|
# 命名規範 (v2):
|
||||||
|
# {service}_{type}_v2_{YYYYMMDD}_{HHMMSS}.{ext}
|
||||||
|
#
|
||||||
|
# 版本說明:
|
||||||
|
# v1: 初始備份架構(不包含新架構組件)
|
||||||
|
# v2: 新架構備份(包含 monitor_jobs, processor_results, Output 目錄)
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# ./backup_all.sh [service|all] [type] [timestamp]
|
||||||
|
#
|
||||||
|
# 參數:
|
||||||
|
# service - 特定服務 (postgresql, redis, mariadb, wordpress, n8n, qdrant, gitea, ollama, caddy, sftpgo, mongodb, php, momentry_output)
|
||||||
|
# all - 備份所有服務 (默認)
|
||||||
|
# type - 備份類型 (full, db, cfg, data)
|
||||||
|
# timestamp - 指定時間戳 (格式: YYYYMMDD_HHMMSS)
|
||||||
|
#
|
||||||
|
# 示例:
|
||||||
|
# ./backup_all.sh # 備份所有服務 (v2)
|
||||||
|
# ./backup_all.sh postgresql # 只備份 PostgreSQL
|
||||||
|
# ./backup_all.sh all full # 完整備份所有服務 (v2)
|
||||||
|
# ./backup_all.sh mariadb db # 只備份 MariaDB 數據庫
|
||||||
|
# ./backup_all.sh restore 20260316_101215 # 恢復到指定斷點
|
||||||
|
#
|
||||||
|
# ⚠️ v2 版本差異:
|
||||||
|
# - 新增 monitor_jobs, processor_results 表
|
||||||
|
# - 新增 Output 目錄備份
|
||||||
|
# - MongoDB 路徑修正
|
||||||
|
#
|
||||||
|
# 排程範例 (crontab):
|
||||||
|
# # 每天凌晨 3 點執行所有備份
|
||||||
|
# 0 3 * * * /Users/accusys/momentry/scripts/backup_all.sh >> /Users/accusys/momentry/log/backup.log 2>&1
|
||||||
|
#
|
||||||
|
# # 每週日凌晨 3 點執行完整備份
|
||||||
|
# 0 3 * * 0 /Users/accusys/momentry/scripts/backup_all.sh all full >> /Users/accusys/momentry/log/backup.log 2>&1
|
||||||
|
#===============================================================================
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# 載入密碼配置
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
if [ -f "$SCRIPT_DIR/load_credentials.sh" ]; then
|
||||||
|
source "$SCRIPT_DIR/load_credentials.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 確保路徑正確(Crontab 環境可能缺少 PATH)
|
||||||
|
export PATH="/usr/local/bin:/opt/homebrew/bin:/opt/homebrew/opt/postgresql@18/bin:/sbin:/usr/sbin:/usr/bin:/bin:/opt/homebrew/opt/mysql-client/bin"
|
||||||
|
|
||||||
|
# 顏色定義
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# 路徑配置
|
||||||
|
BACKUP_ROOT="/Users/accusys/momentry/backup/daily"
|
||||||
|
LOG_DIR="/Users/accusys/momentry/log"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# 備份版本 (v2 = 新架構)
|
||||||
|
BACKUP_VERSION="v2"
|
||||||
|
|
||||||
|
# 時間戳 (v2 格式: v2_YYYYMMDD_HHMMSS)
|
||||||
|
if [ -n "$3" ]; then
|
||||||
|
TIMESTAMP="$3"
|
||||||
|
else
|
||||||
|
TIMESTAMP="${BACKUP_VERSION}_$(date +%Y%m%d_%H%M%S)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 服務列表 (v2 新增 momentry_output)
|
||||||
|
SERVICES=("postgresql" "redis" "mariadb" "wordpress" "n8n" "qdrant" "gitea" "ollama" "caddy" "sftpgo" "mongodb" "php" "momentry_output")
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
# 日誌函數
|
||||||
|
#===============================================================================
|
||||||
|
log() {
|
||||||
|
echo -e "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_DIR/backup.log"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_success() {
|
||||||
|
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] ✅ $1${NC}" | tee -a "$LOG_DIR/backup.log"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ❌ $1${NC}" | tee -a "$LOG_DIR/backup.log"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_warn() {
|
||||||
|
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] ⚠️ $1${NC}" | tee -a "$LOG_DIR/backup.log"
|
||||||
|
}
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
# 通用函數
|
||||||
|
#===============================================================================
|
||||||
|
ensure_backup_dir() {
|
||||||
|
local service=$1
|
||||||
|
mkdir -p "$BACKUP_ROOT/$service"
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_file() {
|
||||||
|
local service=$1
|
||||||
|
local type=$2
|
||||||
|
local file=$3
|
||||||
|
|
||||||
|
ensure_backup_dir "$service"
|
||||||
|
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
local filename=$(basename "$file")
|
||||||
|
local dest="$BACKUP_ROOT/$service/${service}_${type}_${TIMESTAMP}_${filename}"
|
||||||
|
cp "$file" "$dest"
|
||||||
|
|
||||||
|
# 壓縮
|
||||||
|
if [[ "$filename" == *.sql ]]; then
|
||||||
|
gzip "$dest"
|
||||||
|
dest="${dest}.gz"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SHA256
|
||||||
|
sha256sum "$dest" >"${dest}.sha256"
|
||||||
|
|
||||||
|
log_success "$service $type: $(basename "$dest")"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_directory() {
|
||||||
|
local service=$1
|
||||||
|
local type=$2
|
||||||
|
local dir=$3
|
||||||
|
|
||||||
|
ensure_backup_dir "$service"
|
||||||
|
|
||||||
|
if [ -d "$dir" ]; then
|
||||||
|
local dest="$BACKUP_ROOT/$service/${service}_${type}_${TIMESTAMP}.tar.gz"
|
||||||
|
tar -czf "$dest" -C "$(dirname "$dir")" "$(basename "$dir")" 2>/dev/null || true
|
||||||
|
|
||||||
|
# SHA256
|
||||||
|
sha256sum "$dest" >"${dest}.sha256"
|
||||||
|
|
||||||
|
log_success "$service $type: $(basename "$dest")"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
# 服務備份函數
|
||||||
|
#===============================================================================
|
||||||
|
|
||||||
|
# PostgreSQL
|
||||||
|
backup_postgresql() {
|
||||||
|
local type=${1:-db}
|
||||||
|
log "開始 PostgreSQL 備份..."
|
||||||
|
|
||||||
|
# momentry 數據庫
|
||||||
|
PGPASSWORD="$PG_PASSWORD" pg_dump -U "$PG_USER" -d momentry | gzip >"$BACKUP_ROOT/postgresql/postgresql_db_momentry_${TIMESTAMP}.sql.gz"
|
||||||
|
sha256sum "$BACKUP_ROOT/postgresql/postgresql_db_momentry_${TIMESTAMP}.sql.gz" >"$BACKUP_ROOT/postgresql/postgresql_db_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
# video_register 數據庫
|
||||||
|
PGPASSWORD="$PG_PASSWORD" pg_dump -U "$PG_USER" -d video_register | gzip >"$BACKUP_ROOT/postgresql/postgresql_db_video_register_${TIMESTAMP}.sql.gz"
|
||||||
|
sha256sum "$BACKUP_ROOT/postgresql/postgresql_db_video_register_${TIMESTAMP}.sql.gz" >>"$BACKUP_ROOT/postgresql/postgresql_db_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
log_success "PostgreSQL: 數據庫備份完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
backup_redis() {
|
||||||
|
local type=${1:-rdb}
|
||||||
|
log "開始 Redis 備份..."
|
||||||
|
|
||||||
|
redis-cli -a "$REDIS_PASSWORD" SAVE >/dev/null 2>&1
|
||||||
|
cp /opt/homebrew/var/db/redis/dump.rdb "$BACKUP_ROOT/redis/redis_rdb_${TIMESTAMP}.rdb"
|
||||||
|
sha256sum "$BACKUP_ROOT/redis/redis_rdb_${TIMESTAMP}.rdb" >"$BACKUP_ROOT/redis/redis_rdb_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
log_success "Redis: RDB 備份完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# MariaDB (包含 WordPress)
|
||||||
|
backup_mariadb() {
|
||||||
|
local type=${1:-db}
|
||||||
|
log "開始 MariaDB 備份..."
|
||||||
|
|
||||||
|
# 所有數據庫
|
||||||
|
mysqldump -u "$MARIADB_USER" -p"$MARIADB_PASSWORD" --all-databases | gzip > \
|
||||||
|
"$BACKUP_ROOT/mariadb/mariadb_db_all_${TIMESTAMP}.sql.gz"
|
||||||
|
sha256sum "$BACKUP_ROOT/mariadb/mariadb_db_all_${TIMESTAMP}.sql.gz" >"$BACKUP_ROOT/mariadb/mariadb_db_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
# WordPress 數據庫
|
||||||
|
mysqldump -u "$MARIADB_USER" -p"$MARIADB_PASSWORD" wordpress | gzip > \
|
||||||
|
"$BACKUP_ROOT/mariadb/mariadb_db_wordpress_${TIMESTAMP}.sql.gz"
|
||||||
|
sha256sum "$BACKUP_ROOT/mariadb/mariadb_db_wordpress_${TIMESTAMP}.sql.gz" >>"$BACKUP_ROOT/mariadb/mariadb_db_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
log_success "MariaDB: 數據庫備份完成 (包含 WordPress)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# WordPress 文件
|
||||||
|
backup_wordpress_files() {
|
||||||
|
local wordpress_dir="/Users/accusys/wordpress/web"
|
||||||
|
local backup_dir="$BACKUP_ROOT/wordpress"
|
||||||
|
|
||||||
|
log "開始 WordPress 文件備份..."
|
||||||
|
|
||||||
|
# 確保備份目錄存在
|
||||||
|
mkdir -p "$backup_dir"
|
||||||
|
|
||||||
|
# 排除不必要的目錄
|
||||||
|
if [ -d "$wordpress_dir" ]; then
|
||||||
|
tar --exclude='wp-content/cache/*' \
|
||||||
|
--exclude='wp-content/uploads/cache/*' \
|
||||||
|
--exclude='.git/*' \
|
||||||
|
-czf "$backup_dir/wordpress_files_${TIMESTAMP}.tar.gz" \
|
||||||
|
-C /Users/accusys/wordpress web/
|
||||||
|
|
||||||
|
sha256sum "$backup_dir/wordpress_files_${TIMESTAMP}.tar.gz" >>"$backup_dir/wordpress_${TIMESTAMP}.sha256" 2>/dev/null ||
|
||||||
|
sha256sum "$backup_dir/wordpress_files_${TIMESTAMP}.tar.gz" >"$backup_dir/wordpress_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
log_success "WordPress: 文件備份完成"
|
||||||
|
else
|
||||||
|
log_error "WordPress 目錄不存在: $wordpress_dir"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# n8n
|
||||||
|
backup_n8n() {
|
||||||
|
local type=${1:-full}
|
||||||
|
log "開始 n8n 備份..."
|
||||||
|
|
||||||
|
# 數據庫
|
||||||
|
PGPASSWORD="$PG_PASSWORD" pg_dump -U "$PG_USER" -d n8n | gzip >"$BACKUP_ROOT/n8n/n8n_db_${TIMESTAMP}.sql.gz"
|
||||||
|
|
||||||
|
# 數據目錄
|
||||||
|
if [ -d "/Users/accusys/momentry/var/n8n" ]; then
|
||||||
|
tar -czf "$BACKUP_ROOT/n8n/n8n_data_${TIMESTAMP}.tar.gz" -C /Users/accusys/momentry/var n8n/
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SHA256
|
||||||
|
sha256sum "$BACKUP_ROOT/n8n"/n8n_* >"$BACKUP_ROOT/n8n/n8n_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
log_success "n8n: 完整備份完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Qdrant
|
||||||
|
backup_qdrant() {
|
||||||
|
local type=${1:-full}
|
||||||
|
log "開始 Qdrant 備份..."
|
||||||
|
|
||||||
|
# 嘗試使用 Snapshots API
|
||||||
|
COLLECTIONS=$(curl -s -H "api-key: $QDRANT_API_KEY" \
|
||||||
|
http://localhost:6333/collections | jq -r '.result[].name' 2>/dev/null || echo "")
|
||||||
|
|
||||||
|
if [ -n "$COLLECTIONS" ] && [ "$COLLECTIONS" != "null" ]; then
|
||||||
|
for COLLECTION in $COLLECTIONS; do
|
||||||
|
curl -X POST -H "api-key: $QDRANT_API_KEY" \
|
||||||
|
"http://localhost:6333/collections/${COLLECTION}/snapshots" \
|
||||||
|
-o "$BACKUP_ROOT/qdrant/qdrant_snapshot_${COLLECTION}_${TIMESTAMP}.tar.gz" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
else
|
||||||
|
# 數據目錄備份
|
||||||
|
tar -czf "$BACKUP_ROOT/qdrant/qdrant_data_${TIMESTAMP}.tar.gz" \
|
||||||
|
-C /Users/accusys/momentry/var qdrant/ 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SHA256
|
||||||
|
sha256sum "$BACKUP_ROOT/qdrant"/qdrant_* >"$BACKUP_ROOT/qdrant/qdrant_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
log_success "Qdrant: 備份完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Gitea
|
||||||
|
backup_gitea() {
|
||||||
|
local type=${1:-full}
|
||||||
|
log "開始 Gitea 備份..."
|
||||||
|
|
||||||
|
# 數據目錄
|
||||||
|
if [ -d "/Users/accusys/momentry/var/gitea" ]; then
|
||||||
|
tar -czf "$BACKUP_ROOT/gitea/gitea_data_${TIMESTAMP}.tar.gz" \
|
||||||
|
-C /Users/accusys/momentry/var gitea/
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 配置目錄
|
||||||
|
if [ -d "/Users/accusys/momentry/etc/gitea" ]; then
|
||||||
|
tar -czf "$BACKUP_ROOT/gitea/gitea_cfg_${TIMESTAMP}.tar.gz" \
|
||||||
|
-C /Users/accusys/momentry/etc gitea/
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SHA256
|
||||||
|
sha256sum "$BACKUP_ROOT/gitea"/gitea_* >"$BACKUP_ROOT/gitea/gitea_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
log_success "Gitea: 完整備份完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ollama
|
||||||
|
backup_ollama() {
|
||||||
|
local type=${1:-cfg}
|
||||||
|
log "開始 Ollama 備份..."
|
||||||
|
|
||||||
|
# 配置目錄
|
||||||
|
if [ -d "/Users/accusys/momentry/etc/ollama" ]; then
|
||||||
|
tar -czf "$BACKUP_ROOT/ollama/ollama_cfg_${TIMESTAMP}.tar.gz" \
|
||||||
|
-C /Users/accusys/momentry/etc ollama/
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 環境變數
|
||||||
|
if [ -f "/Users/accusys/momentry/var/ollama/environment.txt" ]; then
|
||||||
|
cp /Users/accusys/momentry/var/ollama/environment.txt "$BACKUP_ROOT/ollama/ollama_env_${TIMESTAMP}.txt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SHA256
|
||||||
|
sha256sum "$BACKUP_ROOT/ollama"/ollama_* >"$BACKUP_ROOT/ollama/ollama_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
log_success "Ollama: 配置備份完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Caddy
|
||||||
|
backup_caddy() {
|
||||||
|
local type=${1:-cfg}
|
||||||
|
log "開始 Caddy 備份..."
|
||||||
|
|
||||||
|
# 配置
|
||||||
|
if [ -f "/Users/accusys/momentry/etc/Caddyfile" ]; then
|
||||||
|
tar -czf "$BACKUP_ROOT/caddy/caddy_cfg_${TIMESTAMP}.tar.gz" \
|
||||||
|
-C /Users/accusys/momentry/etc Caddyfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SHA256
|
||||||
|
sha256sum "$BACKUP_ROOT/caddy"/caddy_* >"$BACKUP_ROOT/caddy/caddy_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
log_success "Caddy: 配置備份完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# SftpGo
|
||||||
|
backup_sftpgo() {
|
||||||
|
local type=${1:-cfg}
|
||||||
|
log "開始 SftpGo 備份..."
|
||||||
|
|
||||||
|
# 配置
|
||||||
|
if [ -d "/Users/accusys/momentry/etc/sftpgo" ]; then
|
||||||
|
tar -czf "$BACKUP_ROOT/sftpgo/sftpgo_cfg_${TIMESTAMP}.tar.gz" \
|
||||||
|
-C /Users/accusys/momentry/etc sftpgo/
|
||||||
|
fi
|
||||||
|
|
||||||
|
# PostgreSQL 數據庫 (SFTPGo 已遷移到 PostgreSQL)
|
||||||
|
PGPASSWORD="$SFTPGO_PASSWORD" pg_dump -U "$SFTPGO_USER" -h localhost -d sftpgo | gzip >"$BACKUP_ROOT/sftpgo/sftpgo_db_${TIMESTAMP}.sql.gz"
|
||||||
|
|
||||||
|
# SHA256
|
||||||
|
sha256sum "$BACKUP_ROOT/sftpgo"/sftpgo_* >"$BACKUP_ROOT/sftpgo/sftpgo_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
log_success "SftpGo: 配置和數據庫備份完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# MongoDB
|
||||||
|
backup_mongodb() {
|
||||||
|
local type=${1:-full}
|
||||||
|
log "開始 MongoDB 備份..."
|
||||||
|
|
||||||
|
# 使用 mongodump 備份 (避免文件鎖問題)
|
||||||
|
local MONGO_BACKUP_DIR="/tmp/mongodb_backup_${TIMESTAMP}"
|
||||||
|
mkdir -p "$MONGO_BACKUP_DIR"
|
||||||
|
|
||||||
|
# mongodump 需要認證
|
||||||
|
if [ -n "$MONGODB_PASSWORD" ]; then
|
||||||
|
mongodump --uri="mongodb://localhost:27017" \
|
||||||
|
--username="$MONGODB_USER" \
|
||||||
|
--password="$MONGODB_PASSWORD" \
|
||||||
|
--authenticationDatabase=admin \
|
||||||
|
--out="$MONGO_BACKUP_DIR" 2>/dev/null || true
|
||||||
|
else
|
||||||
|
mongodump --uri="mongodb://localhost:27017" \
|
||||||
|
--out="$MONGO_BACKUP_DIR" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 打包
|
||||||
|
if [ -d "$MONGO_BACKUP_DIR" ] && [ "$(ls -A $MONGO_BACKUP_DIR 2>/dev/null)" ]; then
|
||||||
|
tar -czf "$BACKUP_ROOT/mongodb/mongodb_data_${TIMESTAMP}.tar.gz" \
|
||||||
|
-C "$MONGO_BACKUP_DIR" .
|
||||||
|
rm -rf "$MONGO_BACKUP_DIR"
|
||||||
|
log "MongoDB: mongodump 備份完成"
|
||||||
|
else
|
||||||
|
log_warn "MongoDB: mongodump 備份失敗或數據庫為空"
|
||||||
|
rm -rf "$MONGO_BACKUP_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SHA256
|
||||||
|
sha256sum "$BACKUP_ROOT/mongodb"/mongodb_* >"$BACKUP_ROOT/mongodb/mongodb_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
log_success "MongoDB: 備份完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# PHP
|
||||||
|
backup_php() {
|
||||||
|
local type=${1:-cfg}
|
||||||
|
log "開始 PHP 備份..."
|
||||||
|
|
||||||
|
# 配置
|
||||||
|
if [ -d "/Users/accusys/momentry/etc/php/8.5" ]; then
|
||||||
|
tar -czf "$BACKUP_ROOT/php/php_cfg_${TIMESTAMP}.tar.gz" \
|
||||||
|
-C /Users/accusys/momentry/etc php/8.5
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SHA256
|
||||||
|
sha256sum "$BACKUP_ROOT/php"/php_* >"$BACKUP_ROOT/php/php_${TIMESTAMP}.sha256"
|
||||||
|
|
||||||
|
log_success "PHP: 配置備份完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Momentry Output 目錄 (v2 新增)
|
||||||
|
backup_momentry_output() {
|
||||||
|
local type=${1:-data}
|
||||||
|
log "開始 Momentry Output 備份..."
|
||||||
|
|
||||||
|
# Output 目錄
|
||||||
|
local OUTPUT_DIR="/Users/accusys/momentry/output"
|
||||||
|
|
||||||
|
if [ -d "$OUTPUT_DIR" ]; then
|
||||||
|
tar -czf "$BACKUP_ROOT/momentry/momentry_output_${TIMESTAMP}.tar.gz" \
|
||||||
|
-C /Users/accusys/momentry output/
|
||||||
|
log "Momentry Output: 備份 $OUTPUT_DIR"
|
||||||
|
else
|
||||||
|
log_warn "Momentry Output: 目錄不存在或為空 ($OUTPUT_DIR)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SHA256
|
||||||
|
sha256sum "$BACKUP_ROOT/momentry"/momentry_output_* >"$BACKUP_ROOT/momentry/momentry_output_${TIMESTAMP}.sha256" 2>/dev/null || true
|
||||||
|
|
||||||
|
log_success "Momentry Output: 備份完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
# 恢復函數
|
||||||
|
#===============================================================================
|
||||||
|
|
||||||
|
restore_postgresql() {
|
||||||
|
local timestamp=$1
|
||||||
|
log "恢復 PostgreSQL..."
|
||||||
|
|
||||||
|
# 找到對應的備份文件
|
||||||
|
local backup_file=$(ls "$BACKUP_ROOT/postgresql"/postgresql_db_momentry_${timestamp}.sql.gz 2>/dev/null | head -1)
|
||||||
|
|
||||||
|
if [ -n "$backup_file" ]; then
|
||||||
|
gunzip -c "$backup_file" | PGPASSWORD="$PG_PASSWORD" psql -U "$PG_USER" -d momentry
|
||||||
|
log_success "PostgreSQL 恢復完成"
|
||||||
|
else
|
||||||
|
log_error "找不到 PostgreSQL 備份文件: $timestamp"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_redis() {
|
||||||
|
local timestamp=$1
|
||||||
|
log "恢復 Redis..."
|
||||||
|
|
||||||
|
local backup_file=$(ls "$BACKUP_ROOT/redis"/redis_rdb_${timestamp}.rdb 2>/dev/null | head -1)
|
||||||
|
|
||||||
|
if [ -n "$backup_file" ]; then
|
||||||
|
redis-cli -a "$REDIS_PASSWORD" SHUTDOWN 2>/dev/null || true
|
||||||
|
cp "$backup_file" /opt/homebrew/var/db/redis/dump.rdb
|
||||||
|
launchctl load /Library/LaunchDaemons/com.momentry.redis.plist 2>/dev/null ||
|
||||||
|
redis-server --daemonize yes --requirepass "$REDIS_PASSWORD"
|
||||||
|
log_success "Redis 恢復完成"
|
||||||
|
else
|
||||||
|
log_error "找不到 Redis 備份文件: $timestamp"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_mariadb() {
|
||||||
|
local timestamp=$1
|
||||||
|
log "恢復 MariaDB (包含 WordPress)..."
|
||||||
|
|
||||||
|
local backup_file=$(ls "$BACKUP_ROOT/mariadb"/mariadb_db_wordpress_${timestamp}.sql.gz 2>/dev/null | head -1)
|
||||||
|
|
||||||
|
if [ -n "$backup_file" ]; then
|
||||||
|
gunzip -c "$backup_file" | mysql -u momentry_backup -pmomentry_backup_pwd_2026 wordpress
|
||||||
|
log_success "MariaDB/WordPress 恢復完成"
|
||||||
|
else
|
||||||
|
log_error "找不到 MariaDB 備份文件: $timestamp"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_n8n() {
|
||||||
|
local timestamp=$1
|
||||||
|
log "恢復 n8n..."
|
||||||
|
|
||||||
|
# 恢復數據庫
|
||||||
|
local db_backup=$(ls "$BACKUP_ROOT/n8n"/n8n_db_${timestamp}.sql.gz 2>/dev/null | head -1)
|
||||||
|
if [ -n "$db_backup" ]; then
|
||||||
|
gunzip -c "$db_backup" | PGPASSWORD="$PG_PASSWORD" psql -U "$PG_USER" -d n8n
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 恢復數據目錄
|
||||||
|
local data_backup=$(ls "$BACKUP_ROOT/n8n"/n8n_data_${timestamp}.tar.gz 2>/dev/null | head -1)
|
||||||
|
if [ -n "$data_backup" ]; then
|
||||||
|
rm -rf /Users/accusys/momentry/var/n8n
|
||||||
|
tar -xzf "$data_backup" -C /Users/accusys/momentry/var/
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "n8n 恢復完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_qdrant() {
|
||||||
|
local timestamp=$1
|
||||||
|
log "恢復 Qdrant..."
|
||||||
|
|
||||||
|
pkill qdrant 2>/dev/null || true
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
local data_backup=$(ls "$BACKUP_ROOT/qdrant"/qdrant_data_${timestamp}.tar.gz 2>/dev/null | head -1)
|
||||||
|
if [ -n "$data_backup" ]; then
|
||||||
|
rm -rf /Users/accusys/momentry/var/qdrant
|
||||||
|
tar -xzf "$data_backup" -C /Users/accusys/momentry/var/
|
||||||
|
fi
|
||||||
|
|
||||||
|
launchctl load /Library/LaunchDaemons/com.momentry.qdrant.plist 2>/dev/null || true
|
||||||
|
log_success "Qdrant 恢復完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_gitea() {
|
||||||
|
local timestamp=$1
|
||||||
|
log "恢復 Gitea..."
|
||||||
|
|
||||||
|
# 停止 Gitea
|
||||||
|
pkill gitea 2>/dev/null || true
|
||||||
|
|
||||||
|
# 恢復數據
|
||||||
|
local data_backup=$(ls "$BACKUP_ROOT/gitea"/gitea_data_${timestamp}.tar.gz 2>/dev/null | head -1)
|
||||||
|
if [ -n "$data_backup" ]; then
|
||||||
|
rm -rf /Users/accusys/momentry/var/gitea
|
||||||
|
tar -xzf "$data_backup" -C /Users/accusys/momentry/var/
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 恢復配置
|
||||||
|
local cfg_backup=$(ls "$BACKUP_ROOT/gitea"/gitea_cfg_${timestamp}.tar.gz 2>/dev/null | head -1)
|
||||||
|
if [ -n "$cfg_backup" ]; then
|
||||||
|
rm -rf /Users/accusys/momentry/etc/gitea
|
||||||
|
tar -xzf "$cfg_backup" -C /Users/accusys/momentry/etc/
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "Gitea 恢復完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_ollama() {
|
||||||
|
local timestamp=$1
|
||||||
|
log "恢復 Ollama..."
|
||||||
|
|
||||||
|
# 恢復配置
|
||||||
|
local cfg_backup=$(ls "$BACKUP_ROOT/ollama"/ollama_cfg_${timestamp}.tar.gz 2>/dev/null | head -1)
|
||||||
|
if [ -n "$cfg_backup" ]; then
|
||||||
|
rm -rf /Users/accusys/momentry/etc/ollama
|
||||||
|
tar -xzf "$cfg_backup" -C /Users/accusys/momentry/etc/
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "Ollama 恢復完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_caddy() {
|
||||||
|
local timestamp=$1
|
||||||
|
log "恢復 Caddy..."
|
||||||
|
|
||||||
|
local cfg_backup=$(ls "$BACKUP_ROOT/caddy"/caddy_cfg_${timestamp}.tar.gz 2>/dev/null | head -1)
|
||||||
|
if [ -n "$cfg_backup" ]; then
|
||||||
|
tar -xzf "$cfg_backup" -C /Users/accusys/momentry/etc/
|
||||||
|
caddy reload --config /Users/accusys/momentry/etc/Caddyfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "Caddy 恢復完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_sftpgo() {
|
||||||
|
local timestamp=$1
|
||||||
|
log "恢復 SftpGo..."
|
||||||
|
|
||||||
|
# 停止 SFTPGo
|
||||||
|
pkill -f sftpgo || true
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# 恢復配置
|
||||||
|
local cfg_backup=$(ls "$BACKUP_ROOT/sftpgo"/sftpgo_cfg_${timestamp}.tar.gz 2>/dev/null | head -1)
|
||||||
|
if [ -n "$cfg_backup" ]; then
|
||||||
|
rm -rf /Users/accusys/momentry/etc/sftpgo
|
||||||
|
tar -xzf "$cfg_backup" -C /Users/accusys/momentry/etc/
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 恢復 PostgreSQL 數據庫
|
||||||
|
local db_backup=$(ls "$BACKUP_ROOT/sftpgo"/sftpgo_db_${timestamp}.sql.gz 2>/dev/null | head -1)
|
||||||
|
if [ -n "$db_backup" ]; then
|
||||||
|
# 確保數據庫存在
|
||||||
|
PGPASSWORD="$PG_PASSWORD" psql -U "$PG_USER" -h localhost -d postgres -c "DROP DATABASE IF EXISTS sftpgo;" 2>/dev/null
|
||||||
|
PGPASSWORD="$PG_PASSWORD" psql -U "$PG_USER" -h localhost -d postgres -c "CREATE DATABASE sftpgo OWNER $SFTPGO_USER;" 2>/dev/null
|
||||||
|
gunzip -c "$db_backup" | PGPASSWORD="$SFTPGO_PASSWORD" psql -U "$SFTPGO_USER" -h localhost -d sftpgo 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 重啟 SFTPGo
|
||||||
|
cd /Users/accusys/momentry/var/sftpgo
|
||||||
|
/opt/homebrew/opt/sftpgo/bin/sftpgo serve --config-file /Users/accusys/momentry/etc/sftpgo/sftpgo.json &
|
||||||
|
|
||||||
|
log_success "SftpGo 恢復完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_mongodb() {
|
||||||
|
local timestamp=$1
|
||||||
|
log "恢復 MongoDB..."
|
||||||
|
|
||||||
|
# 解壓縮到臨時目錄
|
||||||
|
local MONGO_RESTORE_DIR="/tmp/mongodb_restore_${timestamp}"
|
||||||
|
mkdir -p "$MONGO_RESTORE_DIR"
|
||||||
|
|
||||||
|
local data_backup=$(ls "$BACKUP_ROOT/mongodb"/mongodb_data_${timestamp}.tar.gz 2>/dev/null | head -1)
|
||||||
|
if [ -n "$data_backup" ]; then
|
||||||
|
tar -xzf "$data_backup" -C "$MONGO_RESTORE_DIR/"
|
||||||
|
|
||||||
|
# 使用 mongorestore 恢復
|
||||||
|
if [ -n "$MONGODB_PASSWORD" ]; then
|
||||||
|
mongorestore --uri="mongodb://localhost:27017" \
|
||||||
|
--username="$MONGODB_USER" \
|
||||||
|
--password="$MONGODB_PASSWORD" \
|
||||||
|
--authenticationDatabase=admin \
|
||||||
|
--drop \
|
||||||
|
--dir="$MONGO_RESTORE_DIR" 2>/dev/null || true
|
||||||
|
else
|
||||||
|
mongorestore --uri="mongodb://localhost:27017" \
|
||||||
|
--drop \
|
||||||
|
--dir="$MONGO_RESTORE_DIR" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf "$MONGO_RESTORE_DIR"
|
||||||
|
else
|
||||||
|
log_warn "MongoDB: 未找到備份文件"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "MongoDB 恢復完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_php() {
|
||||||
|
local timestamp=$1
|
||||||
|
log "恢復 PHP..."
|
||||||
|
|
||||||
|
local cfg_backup=$(ls "$BACKUP_ROOT/php"/php_cfg_${timestamp}.tar.gz 2>/dev/null | head -1)
|
||||||
|
if [ -n "$cfg_backup" ]; then
|
||||||
|
rm -rf /Users/accusys/momentry/etc/php/8.5
|
||||||
|
tar -xzf "$cfg_backup" -C /Users/accusys/momentry/etc/php/
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "PHP 恢復完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_momentry_output() {
|
||||||
|
local timestamp=$1
|
||||||
|
log "恢復 Momentry Output..."
|
||||||
|
|
||||||
|
# v2: Output 目錄可能有多個版本,嘗試 v2 版本再回退到舊版本
|
||||||
|
local output_backup=""
|
||||||
|
|
||||||
|
# 嘗試 v2 版本
|
||||||
|
output_backup=$(ls "$BACKUP_ROOT/momentry"/momentry_output_v2_${timestamp}.tar.gz 2>/dev/null | head -1)
|
||||||
|
|
||||||
|
# 如果沒有 v2 版本,嘗試舊格式
|
||||||
|
if [ -z "$output_backup" ]; then
|
||||||
|
output_backup=$(ls "$BACKUP_ROOT/momentry"/momentry_output_${timestamp}.tar.gz 2>/dev/null | head -1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$output_backup" ]; then
|
||||||
|
rm -rf /Users/accusys/momentry/output
|
||||||
|
mkdir -p /Users/accusys/momentry
|
||||||
|
tar -xzf "$output_backup" -C /Users/accusys/momentry/
|
||||||
|
log "Momentry Output: 恢復 $(basename $output_backup)"
|
||||||
|
else
|
||||||
|
log_warn "Momentry Output: 未找到備份檔案"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "Momentry Output 恢復完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
# 主程序
|
||||||
|
#===============================================================================
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local command=${1:-all}
|
||||||
|
local service=${2:-}
|
||||||
|
local type=${3:-}
|
||||||
|
|
||||||
|
# 確保日誌目錄存在
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
log "=========================================="
|
||||||
|
log "Momentry 備份系統"
|
||||||
|
log "時間戳: $TIMESTAMP"
|
||||||
|
log "=========================================="
|
||||||
|
|
||||||
|
case $command in
|
||||||
|
restore | rollback)
|
||||||
|
if [ -z "$service" ]; then
|
||||||
|
log_error "請指定恢復時間戳 (YYYYMMDD_HHMMSS 或 v2_YYYYMMDD_HHMMSS)"
|
||||||
|
echo "示例: $0 restore v2_20260325_030000"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "開始恢復到斷點: $service"
|
||||||
|
|
||||||
|
for svc in "${SERVICES[@]}"; do
|
||||||
|
case $svc in
|
||||||
|
postgresql) restore_postgresql "$service" ;;
|
||||||
|
redis) restore_redis "$service" ;;
|
||||||
|
mariadb) restore_mariadb "$service" ;;
|
||||||
|
n8n) restore_n8n "$service" ;;
|
||||||
|
qdrant) restore_qdrant "$service" ;;
|
||||||
|
gitea) restore_gitea "$service" ;;
|
||||||
|
ollama) restore_ollama "$service" ;;
|
||||||
|
caddy) restore_caddy "$service" ;;
|
||||||
|
sftpgo) restore_sftpgo "$service" ;;
|
||||||
|
mongodb) restore_mongodb "$service" ;;
|
||||||
|
php) restore_php "$service" ;;
|
||||||
|
momentry_output) restore_momentry_output "$service" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
log "=========================================="
|
||||||
|
log_success "恢復完成!"
|
||||||
|
log "=========================================="
|
||||||
|
;;
|
||||||
|
|
||||||
|
list)
|
||||||
|
log "可用時間點:"
|
||||||
|
for dir in "$BACKUP_ROOT"/*/; do
|
||||||
|
local svc=$(basename "$dir")
|
||||||
|
echo " $svc:"
|
||||||
|
ls -1 "$dir"*.tar.gz "$dir"*.sql.gz "$dir"*.rdb 2>/dev/null |
|
||||||
|
sed 's/.*\([0-9]\{8\}\_[0-9]\{6\}\).*/\1/' | sort -u | sed 's/^/ /'
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
|
||||||
|
status)
|
||||||
|
log "備份狀態:"
|
||||||
|
echo ""
|
||||||
|
for svc in "${SERVICES[@]}"; do
|
||||||
|
local date_part="${TIMESTAMP#*_}" # Remove v2_ prefix
|
||||||
|
date_part="${date_part:0:8}" # Extract YYYYMMDD
|
||||||
|
local latest=$(find "$BACKUP_ROOT/$svc" \( -name "*_${date_part}_*" -o -name "*_v2_${date_part}_*" \) -type f 2>/dev/null | head -1)
|
||||||
|
if [ -n "$latest" ]; then
|
||||||
|
local size=$(du -h "$latest" | cut -f1)
|
||||||
|
echo -e " $svc: ${GREEN}✓${NC} $size"
|
||||||
|
else
|
||||||
|
echo -e " $svc: ${RED}✗${NC}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
|
||||||
|
all)
|
||||||
|
# 備份所有服務
|
||||||
|
for svc in "${SERVICES[@]}"; do
|
||||||
|
case $svc in
|
||||||
|
postgresql) backup_postgresql "$type" ;;
|
||||||
|
redis) backup_redis "$type" ;;
|
||||||
|
mariadb) backup_mariadb "$type" ;;
|
||||||
|
wordpress) backup_wordpress_files ;;
|
||||||
|
n8n) backup_n8n "$type" ;;
|
||||||
|
qdrant) backup_qdrant "$type" ;;
|
||||||
|
gitea) backup_gitea "$type" ;;
|
||||||
|
ollama) backup_ollama "$type" ;;
|
||||||
|
caddy) backup_caddy "$type" ;;
|
||||||
|
sftpgo) backup_sftpgo "$type" ;;
|
||||||
|
mongodb) backup_mongodb "$type" ;;
|
||||||
|
php) backup_php "$type" ;;
|
||||||
|
momentry_output) backup_momentry_output "$type" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
log "=========================================="
|
||||||
|
log_success "所有備份完成! 時間戳: $TIMESTAMP"
|
||||||
|
log "=========================================="
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
# 備份特定服務
|
||||||
|
if [ -n "$service" ]; then
|
||||||
|
case $service in
|
||||||
|
postgresql) backup_postgresql "$type" ;;
|
||||||
|
redis) backup_redis "$type" ;;
|
||||||
|
mariadb) backup_mariadb "$type" ;;
|
||||||
|
wordpress) backup_wordpress_files ;;
|
||||||
|
n8n) backup_n8n "$type" ;;
|
||||||
|
qdrant) backup_qdrant "$type" ;;
|
||||||
|
gitea) backup_gitea "$type" ;;
|
||||||
|
ollama) backup_ollama "$type" ;;
|
||||||
|
caddy) backup_caddy "$type" ;;
|
||||||
|
sftpgo) backup_sftpgo "$type" ;;
|
||||||
|
mongodb) backup_mongodb "$type" ;;
|
||||||
|
php) backup_php "$type" ;;
|
||||||
|
momentry_output) backup_momentry_output "$type" ;;
|
||||||
|
*)
|
||||||
|
log_error "未知服務: $service"
|
||||||
|
echo "可用服務: ${SERVICES[*]}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
log_error "請指定命令或服務"
|
||||||
|
echo "用法: $0 [命令] [服務] [類型]"
|
||||||
|
echo ""
|
||||||
|
echo "命令:"
|
||||||
|
echo " all - 備份所有服務 (默認)"
|
||||||
|
echo " <service> - 備份特定服務"
|
||||||
|
echo " restore - 恢復到指定斷點"
|
||||||
|
echo " list - 列出可用時間點"
|
||||||
|
echo " status - 顯示備份狀態"
|
||||||
|
echo ""
|
||||||
|
echo "服務: ${SERVICES[*]}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
@@ -78,6 +78,15 @@ pub static SERVER_PORT: Lazy<u16> = Lazy::new(|| {
|
|||||||
pub static REDIS_KEY_PREFIX: Lazy<String> =
|
pub static REDIS_KEY_PREFIX: Lazy<String> =
|
||||||
Lazy::new(|| env::var("MOMENTRY_REDIS_PREFIX").unwrap_or_else(|_| "momentry:".to_string()));
|
Lazy::new(|| env::var("MOMENTRY_REDIS_PREFIX").unwrap_or_else(|_| "momentry:".to_string()));
|
||||||
|
|
||||||
|
pub static DATABASE_SCHEMA: Lazy<String> =
|
||||||
|
Lazy::new(|| env::var("DATABASE_SCHEMA").unwrap_or_else(|_| "public".to_string()));
|
||||||
|
|
||||||
|
pub static MONGODB_DATABASE: Lazy<String> =
|
||||||
|
Lazy::new(|| env::var("MONGODB_DATABASE").unwrap_or_else(|_| "momentry".to_string()));
|
||||||
|
|
||||||
|
pub static QDRANT_COLLECTION: Lazy<String> =
|
||||||
|
Lazy::new(|| env::var("QDRANT_COLLECTION").unwrap_or_else(|_| "momentry_rule1".to_string()));
|
||||||
|
|
||||||
pub mod processor {
|
pub mod processor {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
pub mod schema;
|
||||||
|
|
||||||
use crate::core::chunk::Chunk;
|
use crate::core::chunk::Chunk;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|||||||
+655
-299
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
|||||||
|
use crate::core::config::DATABASE_SCHEMA;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
|
pub static SCHEMA_PREFIX: Lazy<String> = Lazy::new(|| {
|
||||||
|
let schema = DATABASE_SCHEMA.as_str();
|
||||||
|
if schema == "public" {
|
||||||
|
String::new()
|
||||||
|
} else {
|
||||||
|
format!("{}.", schema)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pub fn table_name(table: &str) -> String {
|
||||||
|
let prefix = SCHEMA_PREFIX.as_str();
|
||||||
|
if prefix.is_empty() {
|
||||||
|
table.to_string()
|
||||||
|
} else {
|
||||||
|
format!("{}{}", prefix, table)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_table_name_public() {
|
||||||
|
assert_eq!(table_name("videos"), "videos");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user