├── .github └── workflows │ ├── deploy.yml │ ├── release-plz.yml │ └── rust-package.yml ├── .sqlx ├── query-071f05b235745d98764840276ecba417d360c78e9db7855f7422e319659bca24.json ├── query-5c43f5b9f0523fd33024229c0d9dfb5bedb87880983cc36b54a5a49ccb8cf4f2.json └── query-cb5dc82817fbd1fcaa3feaa40fec21819e90b60b7a4ea527dd4bdfdddbc076b2.json ├── CHANGELOG.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── deny.toml ├── docker-compose.yml └── src ├── http.rs └── main.rs /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Deployment 2 | 3 | permissions: 4 | contents: write 5 | id-token: write 6 | attestations: write 7 | 8 | on: 9 | release: 10 | types: [published] 11 | 12 | env: 13 | PUBLISH_BINARY_NAMES: ecomdev-download-magento-images 14 | CARGO_INCREMENTAL: 0 15 | CARGO_NET_GIT_FETCH_WITH_CLI: true 16 | CARGO_NET_RETRY: 10 17 | CARGO_TERM_COLOR: always 18 | RUST_BACKTRACE: 1 19 | RUSTFLAGS: -D warnings 20 | RUSTUP_MAX_RETRIES: 10 21 | 22 | defaults: 23 | run: 24 | shell: bash 25 | 26 | jobs: 27 | upload-assets: 28 | name: ${{ matrix.target }} 29 | if: github.repository_owner == 'MyOwner' && startsWith(github.event.release.name, 'my-bin-v') 30 | runs-on: ${{ matrix.os }} 31 | strategy: 32 | matrix: 33 | include: 34 | - target: aarch64-unknown-linux-gnu 35 | os: ubuntu-22.04 36 | - target: aarch64-unknown-linux-musl 37 | os: ubuntu-22.04 38 | - target: aarch64-apple-darwin 39 | os: macos-13 40 | - target: x86_64-unknown-linux-gnu 41 | os: ubuntu-22.04 42 | - target: x86_64-unknown-linux-musl 43 | os: ubuntu-22.04 44 | - target: x86_64-apple-darwin 45 | os: macos-13 46 | - target: x86_64-unknown-freebsd 47 | os: ubuntu-22.04 48 | timeout-minutes: 60 49 | steps: 50 | - name: Checkout repository 51 | uses: actions/checkout@v4 52 | - name: Install Rust toolchain 53 | uses: dtolnay/rust-toolchain@stable 54 | - uses: taiki-e/setup-cross-toolchain-action@v1 55 | with: 56 | target: ${{ matrix.target }} 57 | if: startsWith(matrix.os, 'ubuntu') && !contains(matrix.target, '-musl') 58 | - uses: taiki-e/install-action@v2 59 | with: 60 | tool: cross 61 | if: contains(matrix.target, '-musl') 62 | - uses: taiki-e/upload-rust-binary-action@v1 63 | id: artifact 64 | with: 65 | bin: ${{ env.PUBLISH_BINARY_NAMES }} 66 | target: ${{ matrix.target }} 67 | tar: all 68 | token: ${{ secrets.GITHUB_TOKEN }} 69 | - name: Generate artifact attestation 70 | uses: actions/attest-build-provenance@v2 71 | with: 72 | subject-path: ${{ steps.artifact.outputs.tar }} -------------------------------------------------------------------------------- /.github/workflows/release-plz.yml: -------------------------------------------------------------------------------- 1 | name: Cargo Release 2 | permissions: 3 | pull-requests: write 4 | contents: write 5 | on: 6 | push: 7 | branches: 8 | - main 9 | jobs: 10 | verify: 11 | uses: ./.github/workflows/rust-package.yml 12 | # Release unpublished packages. 13 | release-plz-release: 14 | needs: verify 15 | name: Release-plz release 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v4 20 | with: 21 | fetch-depth: 0 22 | - name: Install Rust toolchain 23 | uses: dtolnay/rust-toolchain@stable 24 | - name: Run release-plz 25 | uses: release-plz/action@v0.5 26 | with: 27 | command: release 28 | env: 29 | CARGO_REGISTRY_TOKEN: ${{ secrets.RELEASE_PLEASE_CARGO }} 30 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 31 | # Create a PR with the new versions and changelog, preparing the next release. 32 | release-plz-pr: 33 | needs: verify 34 | name: Release-plz PR 35 | runs-on: ubuntu-latest 36 | concurrency: 37 | group: release-plz-${{ github.ref }} 38 | cancel-in-progress: false 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v4 42 | with: 43 | fetch-depth: 0 44 | - name: Install Rust toolchain 45 | uses: dtolnay/rust-toolchain@stable 46 | - name: Run release-plz 47 | uses: release-plz/action@v0.5 48 | with: 49 | command: release-pr 50 | env: 51 | CARGO_REGISTRY_TOKEN: ${{ secrets.RELEASE_PLEASE_CARGO }} 52 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/rust-package.yml: -------------------------------------------------------------------------------- 1 | name: Rust Package 2 | env: 3 | CARGO_TERM_COLOR: always 4 | MSRV: '1.80.0' 5 | on: 6 | push: 7 | pull_request: 8 | workflow_call: 9 | jobs: 10 | check: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: dtolnay/rust-toolchain@beta 15 | with: 16 | components: clippy, rustfmt 17 | - uses: Swatinem/rust-cache@v2 18 | with: 19 | save-if: ${{ github.ref == 'refs/heads/main' }} 20 | - name: Check 21 | run: cargo clippy --workspace --all-targets --all-features -- -D warnings 22 | - name: rustfmt 23 | run: cargo fmt --all --check 24 | 25 | check-docs: 26 | runs-on: ubuntu-latest 27 | steps: 28 | - uses: actions/checkout@v4 29 | - uses: dtolnay/rust-toolchain@stable 30 | - uses: Swatinem/rust-cache@v2 31 | with: 32 | save-if: ${{ github.ref == 'refs/heads/main' }} 33 | - name: cargo doc 34 | run: cargo doc --all-features --no-deps 35 | 36 | test-versions: 37 | needs: check 38 | runs-on: ubuntu-latest 39 | strategy: 40 | matrix: 41 | rust: [ stable, beta ] 42 | steps: 43 | - uses: actions/checkout@v4 44 | - uses: dtolnay/rust-toolchain@master 45 | with: 46 | toolchain: ${{ matrix.rust }} 47 | - uses: Swatinem/rust-cache@v2 48 | with: 49 | save-if: ${{ github.ref == 'refs/heads/main' }} 50 | - name: Run tests 51 | run: cargo test --all-features --all-targets 52 | 53 | test-msrv: 54 | needs: check 55 | runs-on: ubuntu-24.04 56 | steps: 57 | - uses: actions/checkout@v4 58 | - uses: dtolnay/rust-toolchain@master 59 | with: 60 | toolchain: ${{ env.MSRV }} 61 | - uses: Swatinem/rust-cache@v2 62 | with: 63 | save-if: ${{ github.ref == 'refs/heads/main' }} 64 | - name: Run tests 65 | run: cargo +${{ env.MSRV }} test 66 | 67 | deny-check: 68 | name: cargo-deny check 69 | runs-on: ubuntu-latest 70 | continue-on-error: ${{ matrix.checks == 'advisories' }} 71 | strategy: 72 | matrix: 73 | checks: 74 | - advisories 75 | - bans licenses sources 76 | steps: 77 | - uses: actions/checkout@v4 78 | - uses: EmbarkStudios/cargo-deny-action@v1 79 | with: 80 | command: check ${{ matrix.checks }} 81 | manifest-path: ./Cargo.toml 82 | rust-version: ${{ env.MSRV }} 83 | -------------------------------------------------------------------------------- /.sqlx/query-071f05b235745d98764840276ecba417d360c78e9db7855f7422e319659bca24.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "MySQL", 3 | "query": "SELECT MIN(value_id) as `min!`, MAX(value_id) as `max!` FROM catalog_product_entity_media_gallery GROUP BY CEIL(value_id / ?)", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "min!", 9 | "type_info": { 10 | "type": "Long", 11 | "flags": "UNSIGNED | BINARY", 12 | "max_size": 10 13 | } 14 | }, 15 | { 16 | "ordinal": 1, 17 | "name": "max!", 18 | "type_info": { 19 | "type": "Long", 20 | "flags": "UNSIGNED | BINARY", 21 | "max_size": 10 22 | } 23 | } 24 | ], 25 | "parameters": { 26 | "Right": 1 27 | }, 28 | "nullable": [ 29 | true, 30 | true 31 | ] 32 | }, 33 | "hash": "071f05b235745d98764840276ecba417d360c78e9db7855f7422e319659bca24" 34 | } 35 | -------------------------------------------------------------------------------- /.sqlx/query-5c43f5b9f0523fd33024229c0d9dfb5bedb87880983cc36b54a5a49ccb8cf4f2.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "MySQL", 3 | "query": "SELECT COUNT(*) as total FROM catalog_product_entity_media_gallery", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "total", 9 | "type_info": { 10 | "type": "LongLong", 11 | "flags": "NOT_NULL | BINARY", 12 | "max_size": 21 13 | } 14 | } 15 | ], 16 | "parameters": { 17 | "Right": 0 18 | }, 19 | "nullable": [ 20 | false 21 | ] 22 | }, 23 | "hash": "5c43f5b9f0523fd33024229c0d9dfb5bedb87880983cc36b54a5a49ccb8cf4f2" 24 | } 25 | -------------------------------------------------------------------------------- /.sqlx/query-cb5dc82817fbd1fcaa3feaa40fec21819e90b60b7a4ea527dd4bdfdddbc076b2.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "MySQL", 3 | "query": "SELECT value as `value!` FROM catalog_product_entity_media_gallery WHERE value_id BETWEEN ? AND ?", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "value!", 9 | "type_info": { 10 | "type": "VarString", 11 | "flags": "", 12 | "max_size": 1020 13 | } 14 | } 15 | ], 16 | "parameters": { 17 | "Right": 2 18 | }, 19 | "nullable": [ 20 | true 21 | ] 22 | }, 23 | "hash": "cb5dc82817fbd1fcaa3feaa40fec21819e90b60b7a4ea527dd4bdfdddbc076b2" 24 | } 25 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | ## [0.1.0](https://github.com/EcomDev/download-magento-images-rs/releases/tag/v0.1.0) - 2025-01-15 11 | 12 | ### Fixed 13 | 14 | - make base url detected as either MagentoMedia or External 15 | 16 | ### Other 17 | 18 | - fix rustfmt suggestions 19 | - add deny.toml for license and advisory check 20 | - add more docker compose to github actions 21 | - change default container for actions 22 | - fix issues with formatting 23 | - add release-plz 24 | - Updates 25 | - CLI tool for downloading images for Magento store 26 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "alloc-no-stdlib" 22 | version = "2.0.4" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" 25 | 26 | [[package]] 27 | name = "alloc-stdlib" 28 | version = "0.2.2" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" 31 | dependencies = [ 32 | "alloc-no-stdlib", 33 | ] 34 | 35 | [[package]] 36 | name = "allocator-api2" 37 | version = "0.2.21" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" 40 | 41 | [[package]] 42 | name = "anstream" 43 | version = "0.6.18" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" 46 | dependencies = [ 47 | "anstyle", 48 | "anstyle-parse", 49 | "anstyle-query", 50 | "anstyle-wincon", 51 | "colorchoice", 52 | "is_terminal_polyfill", 53 | "utf8parse", 54 | ] 55 | 56 | [[package]] 57 | name = "anstyle" 58 | version = "1.0.10" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" 61 | 62 | [[package]] 63 | name = "anstyle-parse" 64 | version = "0.2.6" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" 67 | dependencies = [ 68 | "utf8parse", 69 | ] 70 | 71 | [[package]] 72 | name = "anstyle-query" 73 | version = "1.1.2" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" 76 | dependencies = [ 77 | "windows-sys 0.59.0", 78 | ] 79 | 80 | [[package]] 81 | name = "anstyle-wincon" 82 | version = "3.0.7" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" 85 | dependencies = [ 86 | "anstyle", 87 | "once_cell", 88 | "windows-sys 0.59.0", 89 | ] 90 | 91 | [[package]] 92 | name = "anyhow" 93 | version = "1.0.95" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" 96 | 97 | [[package]] 98 | name = "async-compression" 99 | version = "0.4.18" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522" 102 | dependencies = [ 103 | "brotli", 104 | "flate2", 105 | "futures-core", 106 | "memchr", 107 | "pin-project-lite", 108 | "tokio", 109 | ] 110 | 111 | [[package]] 112 | name = "atoi" 113 | version = "2.0.0" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" 116 | dependencies = [ 117 | "num-traits", 118 | ] 119 | 120 | [[package]] 121 | name = "atomic-waker" 122 | version = "1.1.2" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 125 | 126 | [[package]] 127 | name = "autocfg" 128 | version = "1.4.0" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 131 | 132 | [[package]] 133 | name = "backtrace" 134 | version = "0.3.74" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 137 | dependencies = [ 138 | "addr2line", 139 | "cfg-if", 140 | "libc", 141 | "miniz_oxide", 142 | "object", 143 | "rustc-demangle", 144 | "windows-targets 0.52.6", 145 | ] 146 | 147 | [[package]] 148 | name = "base64" 149 | version = "0.22.1" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 152 | 153 | [[package]] 154 | name = "base64ct" 155 | version = "1.6.0" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" 158 | 159 | [[package]] 160 | name = "bitflags" 161 | version = "2.7.0" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" 164 | dependencies = [ 165 | "serde", 166 | ] 167 | 168 | [[package]] 169 | name = "block-buffer" 170 | version = "0.10.4" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 173 | dependencies = [ 174 | "generic-array", 175 | ] 176 | 177 | [[package]] 178 | name = "brotli" 179 | version = "7.0.0" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" 182 | dependencies = [ 183 | "alloc-no-stdlib", 184 | "alloc-stdlib", 185 | "brotli-decompressor", 186 | ] 187 | 188 | [[package]] 189 | name = "brotli-decompressor" 190 | version = "4.0.1" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" 193 | dependencies = [ 194 | "alloc-no-stdlib", 195 | "alloc-stdlib", 196 | ] 197 | 198 | [[package]] 199 | name = "bumpalo" 200 | version = "3.16.0" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 203 | 204 | [[package]] 205 | name = "byteorder" 206 | version = "1.5.0" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 209 | 210 | [[package]] 211 | name = "bytes" 212 | version = "1.9.0" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" 215 | 216 | [[package]] 217 | name = "cc" 218 | version = "1.2.9" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" 221 | dependencies = [ 222 | "shlex", 223 | ] 224 | 225 | [[package]] 226 | name = "cfg-if" 227 | version = "1.0.0" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 230 | 231 | [[package]] 232 | name = "cfg_aliases" 233 | version = "0.2.1" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 236 | 237 | [[package]] 238 | name = "clap" 239 | version = "4.5.26" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" 242 | dependencies = [ 243 | "clap_builder", 244 | "clap_derive", 245 | ] 246 | 247 | [[package]] 248 | name = "clap_builder" 249 | version = "4.5.26" 250 | source = "registry+https://github.com/rust-lang/crates.io-index" 251 | checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" 252 | dependencies = [ 253 | "anstream", 254 | "anstyle", 255 | "clap_lex", 256 | "strsim", 257 | ] 258 | 259 | [[package]] 260 | name = "clap_derive" 261 | version = "4.5.24" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" 264 | dependencies = [ 265 | "heck", 266 | "proc-macro2", 267 | "quote", 268 | "syn", 269 | ] 270 | 271 | [[package]] 272 | name = "clap_lex" 273 | version = "0.7.4" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" 276 | 277 | [[package]] 278 | name = "colorchoice" 279 | version = "1.0.3" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" 282 | 283 | [[package]] 284 | name = "concurrent-queue" 285 | version = "2.5.0" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 288 | dependencies = [ 289 | "crossbeam-utils", 290 | ] 291 | 292 | [[package]] 293 | name = "console" 294 | version = "0.15.10" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" 297 | dependencies = [ 298 | "encode_unicode", 299 | "libc", 300 | "once_cell", 301 | "unicode-width", 302 | "windows-sys 0.59.0", 303 | ] 304 | 305 | [[package]] 306 | name = "const-oid" 307 | version = "0.9.6" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" 310 | 311 | [[package]] 312 | name = "cpufeatures" 313 | version = "0.2.16" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" 316 | dependencies = [ 317 | "libc", 318 | ] 319 | 320 | [[package]] 321 | name = "crc" 322 | version = "3.2.1" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" 325 | dependencies = [ 326 | "crc-catalog", 327 | ] 328 | 329 | [[package]] 330 | name = "crc-catalog" 331 | version = "2.4.0" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" 334 | 335 | [[package]] 336 | name = "crc32fast" 337 | version = "1.4.2" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 340 | dependencies = [ 341 | "cfg-if", 342 | ] 343 | 344 | [[package]] 345 | name = "crossbeam-queue" 346 | version = "0.3.12" 347 | source = "registry+https://github.com/rust-lang/crates.io-index" 348 | checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" 349 | dependencies = [ 350 | "crossbeam-utils", 351 | ] 352 | 353 | [[package]] 354 | name = "crossbeam-utils" 355 | version = "0.8.21" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" 358 | 359 | [[package]] 360 | name = "crypto-common" 361 | version = "0.1.6" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 364 | dependencies = [ 365 | "generic-array", 366 | "typenum", 367 | ] 368 | 369 | [[package]] 370 | name = "der" 371 | version = "0.7.9" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" 374 | dependencies = [ 375 | "const-oid", 376 | "pem-rfc7468", 377 | "zeroize", 378 | ] 379 | 380 | [[package]] 381 | name = "digest" 382 | version = "0.10.7" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 385 | dependencies = [ 386 | "block-buffer", 387 | "const-oid", 388 | "crypto-common", 389 | "subtle", 390 | ] 391 | 392 | [[package]] 393 | name = "displaydoc" 394 | version = "0.2.5" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 397 | dependencies = [ 398 | "proc-macro2", 399 | "quote", 400 | "syn", 401 | ] 402 | 403 | [[package]] 404 | name = "dotenvy" 405 | version = "0.15.7" 406 | source = "registry+https://github.com/rust-lang/crates.io-index" 407 | checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" 408 | 409 | [[package]] 410 | name = "ecomdev-download-magento-images" 411 | version = "0.1.0" 412 | dependencies = [ 413 | "anyhow", 414 | "clap", 415 | "indicatif", 416 | "reqwest", 417 | "sqlx", 418 | "tokio", 419 | ] 420 | 421 | [[package]] 422 | name = "either" 423 | version = "1.13.0" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 426 | dependencies = [ 427 | "serde", 428 | ] 429 | 430 | [[package]] 431 | name = "encode_unicode" 432 | version = "1.0.0" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" 435 | 436 | [[package]] 437 | name = "equivalent" 438 | version = "1.0.1" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 441 | 442 | [[package]] 443 | name = "errno" 444 | version = "0.3.10" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 447 | dependencies = [ 448 | "libc", 449 | "windows-sys 0.59.0", 450 | ] 451 | 452 | [[package]] 453 | name = "etcetera" 454 | version = "0.8.0" 455 | source = "registry+https://github.com/rust-lang/crates.io-index" 456 | checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" 457 | dependencies = [ 458 | "cfg-if", 459 | "home", 460 | "windows-sys 0.48.0", 461 | ] 462 | 463 | [[package]] 464 | name = "event-listener" 465 | version = "5.4.0" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" 468 | dependencies = [ 469 | "concurrent-queue", 470 | "parking", 471 | "pin-project-lite", 472 | ] 473 | 474 | [[package]] 475 | name = "fastrand" 476 | version = "2.3.0" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 479 | 480 | [[package]] 481 | name = "flate2" 482 | version = "1.0.35" 483 | source = "registry+https://github.com/rust-lang/crates.io-index" 484 | checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" 485 | dependencies = [ 486 | "crc32fast", 487 | "miniz_oxide", 488 | ] 489 | 490 | [[package]] 491 | name = "flume" 492 | version = "0.11.1" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" 495 | dependencies = [ 496 | "futures-core", 497 | "futures-sink", 498 | "spin", 499 | ] 500 | 501 | [[package]] 502 | name = "fnv" 503 | version = "1.0.7" 504 | source = "registry+https://github.com/rust-lang/crates.io-index" 505 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 506 | 507 | [[package]] 508 | name = "foldhash" 509 | version = "0.1.4" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" 512 | 513 | [[package]] 514 | name = "form_urlencoded" 515 | version = "1.2.1" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 518 | dependencies = [ 519 | "percent-encoding", 520 | ] 521 | 522 | [[package]] 523 | name = "futures-channel" 524 | version = "0.3.31" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 527 | dependencies = [ 528 | "futures-core", 529 | "futures-sink", 530 | ] 531 | 532 | [[package]] 533 | name = "futures-core" 534 | version = "0.3.31" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 537 | 538 | [[package]] 539 | name = "futures-executor" 540 | version = "0.3.31" 541 | source = "registry+https://github.com/rust-lang/crates.io-index" 542 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" 543 | dependencies = [ 544 | "futures-core", 545 | "futures-task", 546 | "futures-util", 547 | ] 548 | 549 | [[package]] 550 | name = "futures-intrusive" 551 | version = "0.5.0" 552 | source = "registry+https://github.com/rust-lang/crates.io-index" 553 | checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" 554 | dependencies = [ 555 | "futures-core", 556 | "lock_api", 557 | "parking_lot", 558 | ] 559 | 560 | [[package]] 561 | name = "futures-io" 562 | version = "0.3.31" 563 | source = "registry+https://github.com/rust-lang/crates.io-index" 564 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 565 | 566 | [[package]] 567 | name = "futures-sink" 568 | version = "0.3.31" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 571 | 572 | [[package]] 573 | name = "futures-task" 574 | version = "0.3.31" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 577 | 578 | [[package]] 579 | name = "futures-util" 580 | version = "0.3.31" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 583 | dependencies = [ 584 | "futures-core", 585 | "futures-io", 586 | "futures-sink", 587 | "futures-task", 588 | "memchr", 589 | "pin-project-lite", 590 | "pin-utils", 591 | "slab", 592 | ] 593 | 594 | [[package]] 595 | name = "generic-array" 596 | version = "0.14.7" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 599 | dependencies = [ 600 | "typenum", 601 | "version_check", 602 | ] 603 | 604 | [[package]] 605 | name = "getrandom" 606 | version = "0.2.15" 607 | source = "registry+https://github.com/rust-lang/crates.io-index" 608 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 609 | dependencies = [ 610 | "cfg-if", 611 | "js-sys", 612 | "libc", 613 | "wasi", 614 | "wasm-bindgen", 615 | ] 616 | 617 | [[package]] 618 | name = "gimli" 619 | version = "0.31.1" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 622 | 623 | [[package]] 624 | name = "h2" 625 | version = "0.4.7" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" 628 | dependencies = [ 629 | "atomic-waker", 630 | "bytes", 631 | "fnv", 632 | "futures-core", 633 | "futures-sink", 634 | "http", 635 | "indexmap", 636 | "slab", 637 | "tokio", 638 | "tokio-util", 639 | "tracing", 640 | ] 641 | 642 | [[package]] 643 | name = "hashbrown" 644 | version = "0.15.2" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 647 | dependencies = [ 648 | "allocator-api2", 649 | "equivalent", 650 | "foldhash", 651 | ] 652 | 653 | [[package]] 654 | name = "hashlink" 655 | version = "0.10.0" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" 658 | dependencies = [ 659 | "hashbrown", 660 | ] 661 | 662 | [[package]] 663 | name = "heck" 664 | version = "0.5.0" 665 | source = "registry+https://github.com/rust-lang/crates.io-index" 666 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 667 | 668 | [[package]] 669 | name = "hex" 670 | version = "0.4.3" 671 | source = "registry+https://github.com/rust-lang/crates.io-index" 672 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 673 | 674 | [[package]] 675 | name = "hkdf" 676 | version = "0.12.4" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" 679 | dependencies = [ 680 | "hmac", 681 | ] 682 | 683 | [[package]] 684 | name = "hmac" 685 | version = "0.12.1" 686 | source = "registry+https://github.com/rust-lang/crates.io-index" 687 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 688 | dependencies = [ 689 | "digest", 690 | ] 691 | 692 | [[package]] 693 | name = "home" 694 | version = "0.5.11" 695 | source = "registry+https://github.com/rust-lang/crates.io-index" 696 | checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" 697 | dependencies = [ 698 | "windows-sys 0.59.0", 699 | ] 700 | 701 | [[package]] 702 | name = "http" 703 | version = "1.2.0" 704 | source = "registry+https://github.com/rust-lang/crates.io-index" 705 | checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" 706 | dependencies = [ 707 | "bytes", 708 | "fnv", 709 | "itoa", 710 | ] 711 | 712 | [[package]] 713 | name = "http-body" 714 | version = "1.0.1" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 717 | dependencies = [ 718 | "bytes", 719 | "http", 720 | ] 721 | 722 | [[package]] 723 | name = "http-body-util" 724 | version = "0.1.2" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" 727 | dependencies = [ 728 | "bytes", 729 | "futures-util", 730 | "http", 731 | "http-body", 732 | "pin-project-lite", 733 | ] 734 | 735 | [[package]] 736 | name = "httparse" 737 | version = "1.9.5" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" 740 | 741 | [[package]] 742 | name = "hyper" 743 | version = "1.5.2" 744 | source = "registry+https://github.com/rust-lang/crates.io-index" 745 | checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" 746 | dependencies = [ 747 | "bytes", 748 | "futures-channel", 749 | "futures-util", 750 | "http", 751 | "http-body", 752 | "httparse", 753 | "itoa", 754 | "pin-project-lite", 755 | "smallvec", 756 | "tokio", 757 | "want", 758 | ] 759 | 760 | [[package]] 761 | name = "hyper-rustls" 762 | version = "0.27.5" 763 | source = "registry+https://github.com/rust-lang/crates.io-index" 764 | checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" 765 | dependencies = [ 766 | "futures-util", 767 | "http", 768 | "hyper", 769 | "hyper-util", 770 | "rustls", 771 | "rustls-pki-types", 772 | "tokio", 773 | "tokio-rustls", 774 | "tower-service", 775 | "webpki-roots", 776 | ] 777 | 778 | [[package]] 779 | name = "hyper-util" 780 | version = "0.1.10" 781 | source = "registry+https://github.com/rust-lang/crates.io-index" 782 | checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" 783 | dependencies = [ 784 | "bytes", 785 | "futures-channel", 786 | "futures-util", 787 | "http", 788 | "http-body", 789 | "hyper", 790 | "pin-project-lite", 791 | "socket2", 792 | "tokio", 793 | "tower-service", 794 | "tracing", 795 | ] 796 | 797 | [[package]] 798 | name = "icu_collections" 799 | version = "1.5.0" 800 | source = "registry+https://github.com/rust-lang/crates.io-index" 801 | checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" 802 | dependencies = [ 803 | "displaydoc", 804 | "yoke", 805 | "zerofrom", 806 | "zerovec", 807 | ] 808 | 809 | [[package]] 810 | name = "icu_locid" 811 | version = "1.5.0" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" 814 | dependencies = [ 815 | "displaydoc", 816 | "litemap", 817 | "tinystr", 818 | "writeable", 819 | "zerovec", 820 | ] 821 | 822 | [[package]] 823 | name = "icu_locid_transform" 824 | version = "1.5.0" 825 | source = "registry+https://github.com/rust-lang/crates.io-index" 826 | checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" 827 | dependencies = [ 828 | "displaydoc", 829 | "icu_locid", 830 | "icu_locid_transform_data", 831 | "icu_provider", 832 | "tinystr", 833 | "zerovec", 834 | ] 835 | 836 | [[package]] 837 | name = "icu_locid_transform_data" 838 | version = "1.5.0" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" 841 | 842 | [[package]] 843 | name = "icu_normalizer" 844 | version = "1.5.0" 845 | source = "registry+https://github.com/rust-lang/crates.io-index" 846 | checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" 847 | dependencies = [ 848 | "displaydoc", 849 | "icu_collections", 850 | "icu_normalizer_data", 851 | "icu_properties", 852 | "icu_provider", 853 | "smallvec", 854 | "utf16_iter", 855 | "utf8_iter", 856 | "write16", 857 | "zerovec", 858 | ] 859 | 860 | [[package]] 861 | name = "icu_normalizer_data" 862 | version = "1.5.0" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" 865 | 866 | [[package]] 867 | name = "icu_properties" 868 | version = "1.5.1" 869 | source = "registry+https://github.com/rust-lang/crates.io-index" 870 | checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" 871 | dependencies = [ 872 | "displaydoc", 873 | "icu_collections", 874 | "icu_locid_transform", 875 | "icu_properties_data", 876 | "icu_provider", 877 | "tinystr", 878 | "zerovec", 879 | ] 880 | 881 | [[package]] 882 | name = "icu_properties_data" 883 | version = "1.5.0" 884 | source = "registry+https://github.com/rust-lang/crates.io-index" 885 | checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" 886 | 887 | [[package]] 888 | name = "icu_provider" 889 | version = "1.5.0" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" 892 | dependencies = [ 893 | "displaydoc", 894 | "icu_locid", 895 | "icu_provider_macros", 896 | "stable_deref_trait", 897 | "tinystr", 898 | "writeable", 899 | "yoke", 900 | "zerofrom", 901 | "zerovec", 902 | ] 903 | 904 | [[package]] 905 | name = "icu_provider_macros" 906 | version = "1.5.0" 907 | source = "registry+https://github.com/rust-lang/crates.io-index" 908 | checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" 909 | dependencies = [ 910 | "proc-macro2", 911 | "quote", 912 | "syn", 913 | ] 914 | 915 | [[package]] 916 | name = "idna" 917 | version = "1.0.3" 918 | source = "registry+https://github.com/rust-lang/crates.io-index" 919 | checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 920 | dependencies = [ 921 | "idna_adapter", 922 | "smallvec", 923 | "utf8_iter", 924 | ] 925 | 926 | [[package]] 927 | name = "idna_adapter" 928 | version = "1.2.0" 929 | source = "registry+https://github.com/rust-lang/crates.io-index" 930 | checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" 931 | dependencies = [ 932 | "icu_normalizer", 933 | "icu_properties", 934 | ] 935 | 936 | [[package]] 937 | name = "indexmap" 938 | version = "2.7.0" 939 | source = "registry+https://github.com/rust-lang/crates.io-index" 940 | checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" 941 | dependencies = [ 942 | "equivalent", 943 | "hashbrown", 944 | ] 945 | 946 | [[package]] 947 | name = "indicatif" 948 | version = "0.17.9" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281" 951 | dependencies = [ 952 | "console", 953 | "number_prefix", 954 | "portable-atomic", 955 | "unicode-width", 956 | "web-time", 957 | ] 958 | 959 | [[package]] 960 | name = "ipnet" 961 | version = "2.10.1" 962 | source = "registry+https://github.com/rust-lang/crates.io-index" 963 | checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" 964 | 965 | [[package]] 966 | name = "is_terminal_polyfill" 967 | version = "1.70.1" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 970 | 971 | [[package]] 972 | name = "itoa" 973 | version = "1.0.14" 974 | source = "registry+https://github.com/rust-lang/crates.io-index" 975 | checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" 976 | 977 | [[package]] 978 | name = "js-sys" 979 | version = "0.3.77" 980 | source = "registry+https://github.com/rust-lang/crates.io-index" 981 | checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" 982 | dependencies = [ 983 | "once_cell", 984 | "wasm-bindgen", 985 | ] 986 | 987 | [[package]] 988 | name = "lazy_static" 989 | version = "1.5.0" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 992 | dependencies = [ 993 | "spin", 994 | ] 995 | 996 | [[package]] 997 | name = "libc" 998 | version = "0.2.169" 999 | source = "registry+https://github.com/rust-lang/crates.io-index" 1000 | checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" 1001 | 1002 | [[package]] 1003 | name = "libm" 1004 | version = "0.2.11" 1005 | source = "registry+https://github.com/rust-lang/crates.io-index" 1006 | checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" 1007 | 1008 | [[package]] 1009 | name = "libsqlite3-sys" 1010 | version = "0.30.1" 1011 | source = "registry+https://github.com/rust-lang/crates.io-index" 1012 | checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" 1013 | dependencies = [ 1014 | "pkg-config", 1015 | "vcpkg", 1016 | ] 1017 | 1018 | [[package]] 1019 | name = "linux-raw-sys" 1020 | version = "0.4.15" 1021 | source = "registry+https://github.com/rust-lang/crates.io-index" 1022 | checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 1023 | 1024 | [[package]] 1025 | name = "litemap" 1026 | version = "0.7.4" 1027 | source = "registry+https://github.com/rust-lang/crates.io-index" 1028 | checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" 1029 | 1030 | [[package]] 1031 | name = "lock_api" 1032 | version = "0.4.12" 1033 | source = "registry+https://github.com/rust-lang/crates.io-index" 1034 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 1035 | dependencies = [ 1036 | "autocfg", 1037 | "scopeguard", 1038 | ] 1039 | 1040 | [[package]] 1041 | name = "log" 1042 | version = "0.4.25" 1043 | source = "registry+https://github.com/rust-lang/crates.io-index" 1044 | checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" 1045 | 1046 | [[package]] 1047 | name = "md-5" 1048 | version = "0.10.6" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" 1051 | dependencies = [ 1052 | "cfg-if", 1053 | "digest", 1054 | ] 1055 | 1056 | [[package]] 1057 | name = "memchr" 1058 | version = "2.7.4" 1059 | source = "registry+https://github.com/rust-lang/crates.io-index" 1060 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 1061 | 1062 | [[package]] 1063 | name = "mime" 1064 | version = "0.3.17" 1065 | source = "registry+https://github.com/rust-lang/crates.io-index" 1066 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 1067 | 1068 | [[package]] 1069 | name = "miniz_oxide" 1070 | version = "0.8.3" 1071 | source = "registry+https://github.com/rust-lang/crates.io-index" 1072 | checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" 1073 | dependencies = [ 1074 | "adler2", 1075 | ] 1076 | 1077 | [[package]] 1078 | name = "mio" 1079 | version = "1.0.3" 1080 | source = "registry+https://github.com/rust-lang/crates.io-index" 1081 | checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 1082 | dependencies = [ 1083 | "libc", 1084 | "wasi", 1085 | "windows-sys 0.52.0", 1086 | ] 1087 | 1088 | [[package]] 1089 | name = "num-bigint-dig" 1090 | version = "0.8.4" 1091 | source = "registry+https://github.com/rust-lang/crates.io-index" 1092 | checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" 1093 | dependencies = [ 1094 | "byteorder", 1095 | "lazy_static", 1096 | "libm", 1097 | "num-integer", 1098 | "num-iter", 1099 | "num-traits", 1100 | "rand", 1101 | "smallvec", 1102 | "zeroize", 1103 | ] 1104 | 1105 | [[package]] 1106 | name = "num-integer" 1107 | version = "0.1.46" 1108 | source = "registry+https://github.com/rust-lang/crates.io-index" 1109 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 1110 | dependencies = [ 1111 | "num-traits", 1112 | ] 1113 | 1114 | [[package]] 1115 | name = "num-iter" 1116 | version = "0.1.45" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" 1119 | dependencies = [ 1120 | "autocfg", 1121 | "num-integer", 1122 | "num-traits", 1123 | ] 1124 | 1125 | [[package]] 1126 | name = "num-traits" 1127 | version = "0.2.19" 1128 | source = "registry+https://github.com/rust-lang/crates.io-index" 1129 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1130 | dependencies = [ 1131 | "autocfg", 1132 | "libm", 1133 | ] 1134 | 1135 | [[package]] 1136 | name = "number_prefix" 1137 | version = "0.4.0" 1138 | source = "registry+https://github.com/rust-lang/crates.io-index" 1139 | checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 1140 | 1141 | [[package]] 1142 | name = "object" 1143 | version = "0.36.7" 1144 | source = "registry+https://github.com/rust-lang/crates.io-index" 1145 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 1146 | dependencies = [ 1147 | "memchr", 1148 | ] 1149 | 1150 | [[package]] 1151 | name = "once_cell" 1152 | version = "1.20.2" 1153 | source = "registry+https://github.com/rust-lang/crates.io-index" 1154 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 1155 | 1156 | [[package]] 1157 | name = "parking" 1158 | version = "2.2.1" 1159 | source = "registry+https://github.com/rust-lang/crates.io-index" 1160 | checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" 1161 | 1162 | [[package]] 1163 | name = "parking_lot" 1164 | version = "0.12.3" 1165 | source = "registry+https://github.com/rust-lang/crates.io-index" 1166 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1167 | dependencies = [ 1168 | "lock_api", 1169 | "parking_lot_core", 1170 | ] 1171 | 1172 | [[package]] 1173 | name = "parking_lot_core" 1174 | version = "0.9.10" 1175 | source = "registry+https://github.com/rust-lang/crates.io-index" 1176 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1177 | dependencies = [ 1178 | "cfg-if", 1179 | "libc", 1180 | "redox_syscall", 1181 | "smallvec", 1182 | "windows-targets 0.52.6", 1183 | ] 1184 | 1185 | [[package]] 1186 | name = "pem-rfc7468" 1187 | version = "0.7.0" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" 1190 | dependencies = [ 1191 | "base64ct", 1192 | ] 1193 | 1194 | [[package]] 1195 | name = "percent-encoding" 1196 | version = "2.3.1" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1199 | 1200 | [[package]] 1201 | name = "pin-project-lite" 1202 | version = "0.2.16" 1203 | source = "registry+https://github.com/rust-lang/crates.io-index" 1204 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 1205 | 1206 | [[package]] 1207 | name = "pin-utils" 1208 | version = "0.1.0" 1209 | source = "registry+https://github.com/rust-lang/crates.io-index" 1210 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1211 | 1212 | [[package]] 1213 | name = "pkcs1" 1214 | version = "0.7.5" 1215 | source = "registry+https://github.com/rust-lang/crates.io-index" 1216 | checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" 1217 | dependencies = [ 1218 | "der", 1219 | "pkcs8", 1220 | "spki", 1221 | ] 1222 | 1223 | [[package]] 1224 | name = "pkcs8" 1225 | version = "0.10.2" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" 1228 | dependencies = [ 1229 | "der", 1230 | "spki", 1231 | ] 1232 | 1233 | [[package]] 1234 | name = "pkg-config" 1235 | version = "0.3.31" 1236 | source = "registry+https://github.com/rust-lang/crates.io-index" 1237 | checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" 1238 | 1239 | [[package]] 1240 | name = "portable-atomic" 1241 | version = "1.10.0" 1242 | source = "registry+https://github.com/rust-lang/crates.io-index" 1243 | checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" 1244 | 1245 | [[package]] 1246 | name = "ppv-lite86" 1247 | version = "0.2.20" 1248 | source = "registry+https://github.com/rust-lang/crates.io-index" 1249 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 1250 | dependencies = [ 1251 | "zerocopy", 1252 | ] 1253 | 1254 | [[package]] 1255 | name = "proc-macro2" 1256 | version = "1.0.93" 1257 | source = "registry+https://github.com/rust-lang/crates.io-index" 1258 | checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" 1259 | dependencies = [ 1260 | "unicode-ident", 1261 | ] 1262 | 1263 | [[package]] 1264 | name = "quinn" 1265 | version = "0.11.6" 1266 | source = "registry+https://github.com/rust-lang/crates.io-index" 1267 | checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" 1268 | dependencies = [ 1269 | "bytes", 1270 | "pin-project-lite", 1271 | "quinn-proto", 1272 | "quinn-udp", 1273 | "rustc-hash", 1274 | "rustls", 1275 | "socket2", 1276 | "thiserror", 1277 | "tokio", 1278 | "tracing", 1279 | ] 1280 | 1281 | [[package]] 1282 | name = "quinn-proto" 1283 | version = "0.11.9" 1284 | source = "registry+https://github.com/rust-lang/crates.io-index" 1285 | checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" 1286 | dependencies = [ 1287 | "bytes", 1288 | "getrandom", 1289 | "rand", 1290 | "ring", 1291 | "rustc-hash", 1292 | "rustls", 1293 | "rustls-pki-types", 1294 | "slab", 1295 | "thiserror", 1296 | "tinyvec", 1297 | "tracing", 1298 | "web-time", 1299 | ] 1300 | 1301 | [[package]] 1302 | name = "quinn-udp" 1303 | version = "0.5.9" 1304 | source = "registry+https://github.com/rust-lang/crates.io-index" 1305 | checksum = "1c40286217b4ba3a71d644d752e6a0b71f13f1b6a2c5311acfcbe0c2418ed904" 1306 | dependencies = [ 1307 | "cfg_aliases", 1308 | "libc", 1309 | "once_cell", 1310 | "socket2", 1311 | "tracing", 1312 | "windows-sys 0.59.0", 1313 | ] 1314 | 1315 | [[package]] 1316 | name = "quote" 1317 | version = "1.0.38" 1318 | source = "registry+https://github.com/rust-lang/crates.io-index" 1319 | checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" 1320 | dependencies = [ 1321 | "proc-macro2", 1322 | ] 1323 | 1324 | [[package]] 1325 | name = "rand" 1326 | version = "0.8.5" 1327 | source = "registry+https://github.com/rust-lang/crates.io-index" 1328 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1329 | dependencies = [ 1330 | "libc", 1331 | "rand_chacha", 1332 | "rand_core", 1333 | ] 1334 | 1335 | [[package]] 1336 | name = "rand_chacha" 1337 | version = "0.3.1" 1338 | source = "registry+https://github.com/rust-lang/crates.io-index" 1339 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1340 | dependencies = [ 1341 | "ppv-lite86", 1342 | "rand_core", 1343 | ] 1344 | 1345 | [[package]] 1346 | name = "rand_core" 1347 | version = "0.6.4" 1348 | source = "registry+https://github.com/rust-lang/crates.io-index" 1349 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1350 | dependencies = [ 1351 | "getrandom", 1352 | ] 1353 | 1354 | [[package]] 1355 | name = "redox_syscall" 1356 | version = "0.5.8" 1357 | source = "registry+https://github.com/rust-lang/crates.io-index" 1358 | checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" 1359 | dependencies = [ 1360 | "bitflags", 1361 | ] 1362 | 1363 | [[package]] 1364 | name = "reqwest" 1365 | version = "0.12.12" 1366 | source = "registry+https://github.com/rust-lang/crates.io-index" 1367 | checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" 1368 | dependencies = [ 1369 | "async-compression", 1370 | "base64", 1371 | "bytes", 1372 | "futures-core", 1373 | "futures-util", 1374 | "h2", 1375 | "http", 1376 | "http-body", 1377 | "http-body-util", 1378 | "hyper", 1379 | "hyper-rustls", 1380 | "hyper-util", 1381 | "ipnet", 1382 | "js-sys", 1383 | "log", 1384 | "mime", 1385 | "once_cell", 1386 | "percent-encoding", 1387 | "pin-project-lite", 1388 | "quinn", 1389 | "rustls", 1390 | "rustls-pemfile", 1391 | "rustls-pki-types", 1392 | "serde", 1393 | "serde_json", 1394 | "serde_urlencoded", 1395 | "sync_wrapper", 1396 | "tokio", 1397 | "tokio-rustls", 1398 | "tokio-util", 1399 | "tower", 1400 | "tower-service", 1401 | "url", 1402 | "wasm-bindgen", 1403 | "wasm-bindgen-futures", 1404 | "web-sys", 1405 | "webpki-roots", 1406 | "windows-registry", 1407 | ] 1408 | 1409 | [[package]] 1410 | name = "ring" 1411 | version = "0.17.8" 1412 | source = "registry+https://github.com/rust-lang/crates.io-index" 1413 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 1414 | dependencies = [ 1415 | "cc", 1416 | "cfg-if", 1417 | "getrandom", 1418 | "libc", 1419 | "spin", 1420 | "untrusted", 1421 | "windows-sys 0.52.0", 1422 | ] 1423 | 1424 | [[package]] 1425 | name = "rsa" 1426 | version = "0.9.7" 1427 | source = "registry+https://github.com/rust-lang/crates.io-index" 1428 | checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" 1429 | dependencies = [ 1430 | "const-oid", 1431 | "digest", 1432 | "num-bigint-dig", 1433 | "num-integer", 1434 | "num-traits", 1435 | "pkcs1", 1436 | "pkcs8", 1437 | "rand_core", 1438 | "signature", 1439 | "spki", 1440 | "subtle", 1441 | "zeroize", 1442 | ] 1443 | 1444 | [[package]] 1445 | name = "rustc-demangle" 1446 | version = "0.1.24" 1447 | source = "registry+https://github.com/rust-lang/crates.io-index" 1448 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1449 | 1450 | [[package]] 1451 | name = "rustc-hash" 1452 | version = "2.1.0" 1453 | source = "registry+https://github.com/rust-lang/crates.io-index" 1454 | checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" 1455 | 1456 | [[package]] 1457 | name = "rustix" 1458 | version = "0.38.43" 1459 | source = "registry+https://github.com/rust-lang/crates.io-index" 1460 | checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" 1461 | dependencies = [ 1462 | "bitflags", 1463 | "errno", 1464 | "libc", 1465 | "linux-raw-sys", 1466 | "windows-sys 0.59.0", 1467 | ] 1468 | 1469 | [[package]] 1470 | name = "rustls" 1471 | version = "0.23.21" 1472 | source = "registry+https://github.com/rust-lang/crates.io-index" 1473 | checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" 1474 | dependencies = [ 1475 | "once_cell", 1476 | "ring", 1477 | "rustls-pki-types", 1478 | "rustls-webpki", 1479 | "subtle", 1480 | "zeroize", 1481 | ] 1482 | 1483 | [[package]] 1484 | name = "rustls-pemfile" 1485 | version = "2.2.0" 1486 | source = "registry+https://github.com/rust-lang/crates.io-index" 1487 | checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" 1488 | dependencies = [ 1489 | "rustls-pki-types", 1490 | ] 1491 | 1492 | [[package]] 1493 | name = "rustls-pki-types" 1494 | version = "1.10.1" 1495 | source = "registry+https://github.com/rust-lang/crates.io-index" 1496 | checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" 1497 | dependencies = [ 1498 | "web-time", 1499 | ] 1500 | 1501 | [[package]] 1502 | name = "rustls-webpki" 1503 | version = "0.102.8" 1504 | source = "registry+https://github.com/rust-lang/crates.io-index" 1505 | checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" 1506 | dependencies = [ 1507 | "ring", 1508 | "rustls-pki-types", 1509 | "untrusted", 1510 | ] 1511 | 1512 | [[package]] 1513 | name = "rustversion" 1514 | version = "1.0.19" 1515 | source = "registry+https://github.com/rust-lang/crates.io-index" 1516 | checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" 1517 | 1518 | [[package]] 1519 | name = "ryu" 1520 | version = "1.0.18" 1521 | source = "registry+https://github.com/rust-lang/crates.io-index" 1522 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 1523 | 1524 | [[package]] 1525 | name = "scopeguard" 1526 | version = "1.2.0" 1527 | source = "registry+https://github.com/rust-lang/crates.io-index" 1528 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1529 | 1530 | [[package]] 1531 | name = "serde" 1532 | version = "1.0.217" 1533 | source = "registry+https://github.com/rust-lang/crates.io-index" 1534 | checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" 1535 | dependencies = [ 1536 | "serde_derive", 1537 | ] 1538 | 1539 | [[package]] 1540 | name = "serde_derive" 1541 | version = "1.0.217" 1542 | source = "registry+https://github.com/rust-lang/crates.io-index" 1543 | checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" 1544 | dependencies = [ 1545 | "proc-macro2", 1546 | "quote", 1547 | "syn", 1548 | ] 1549 | 1550 | [[package]] 1551 | name = "serde_json" 1552 | version = "1.0.135" 1553 | source = "registry+https://github.com/rust-lang/crates.io-index" 1554 | checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" 1555 | dependencies = [ 1556 | "itoa", 1557 | "memchr", 1558 | "ryu", 1559 | "serde", 1560 | ] 1561 | 1562 | [[package]] 1563 | name = "serde_urlencoded" 1564 | version = "0.7.1" 1565 | source = "registry+https://github.com/rust-lang/crates.io-index" 1566 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1567 | dependencies = [ 1568 | "form_urlencoded", 1569 | "itoa", 1570 | "ryu", 1571 | "serde", 1572 | ] 1573 | 1574 | [[package]] 1575 | name = "sha1" 1576 | version = "0.10.6" 1577 | source = "registry+https://github.com/rust-lang/crates.io-index" 1578 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 1579 | dependencies = [ 1580 | "cfg-if", 1581 | "cpufeatures", 1582 | "digest", 1583 | ] 1584 | 1585 | [[package]] 1586 | name = "sha2" 1587 | version = "0.10.8" 1588 | source = "registry+https://github.com/rust-lang/crates.io-index" 1589 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1590 | dependencies = [ 1591 | "cfg-if", 1592 | "cpufeatures", 1593 | "digest", 1594 | ] 1595 | 1596 | [[package]] 1597 | name = "shlex" 1598 | version = "1.3.0" 1599 | source = "registry+https://github.com/rust-lang/crates.io-index" 1600 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1601 | 1602 | [[package]] 1603 | name = "signature" 1604 | version = "2.2.0" 1605 | source = "registry+https://github.com/rust-lang/crates.io-index" 1606 | checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" 1607 | dependencies = [ 1608 | "digest", 1609 | "rand_core", 1610 | ] 1611 | 1612 | [[package]] 1613 | name = "slab" 1614 | version = "0.4.9" 1615 | source = "registry+https://github.com/rust-lang/crates.io-index" 1616 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1617 | dependencies = [ 1618 | "autocfg", 1619 | ] 1620 | 1621 | [[package]] 1622 | name = "smallvec" 1623 | version = "1.13.2" 1624 | source = "registry+https://github.com/rust-lang/crates.io-index" 1625 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1626 | dependencies = [ 1627 | "serde", 1628 | ] 1629 | 1630 | [[package]] 1631 | name = "socket2" 1632 | version = "0.5.8" 1633 | source = "registry+https://github.com/rust-lang/crates.io-index" 1634 | checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" 1635 | dependencies = [ 1636 | "libc", 1637 | "windows-sys 0.52.0", 1638 | ] 1639 | 1640 | [[package]] 1641 | name = "spin" 1642 | version = "0.9.8" 1643 | source = "registry+https://github.com/rust-lang/crates.io-index" 1644 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1645 | dependencies = [ 1646 | "lock_api", 1647 | ] 1648 | 1649 | [[package]] 1650 | name = "spki" 1651 | version = "0.7.3" 1652 | source = "registry+https://github.com/rust-lang/crates.io-index" 1653 | checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" 1654 | dependencies = [ 1655 | "base64ct", 1656 | "der", 1657 | ] 1658 | 1659 | [[package]] 1660 | name = "sqlx" 1661 | version = "0.8.3" 1662 | source = "registry+https://github.com/rust-lang/crates.io-index" 1663 | checksum = "4410e73b3c0d8442c5f99b425d7a435b5ee0ae4167b3196771dd3f7a01be745f" 1664 | dependencies = [ 1665 | "sqlx-core", 1666 | "sqlx-macros", 1667 | "sqlx-mysql", 1668 | "sqlx-postgres", 1669 | "sqlx-sqlite", 1670 | ] 1671 | 1672 | [[package]] 1673 | name = "sqlx-core" 1674 | version = "0.8.3" 1675 | source = "registry+https://github.com/rust-lang/crates.io-index" 1676 | checksum = "6a007b6936676aa9ab40207cde35daab0a04b823be8ae004368c0793b96a61e0" 1677 | dependencies = [ 1678 | "bytes", 1679 | "crc", 1680 | "crossbeam-queue", 1681 | "either", 1682 | "event-listener", 1683 | "futures-core", 1684 | "futures-intrusive", 1685 | "futures-io", 1686 | "futures-util", 1687 | "hashbrown", 1688 | "hashlink", 1689 | "indexmap", 1690 | "log", 1691 | "memchr", 1692 | "once_cell", 1693 | "percent-encoding", 1694 | "rustls", 1695 | "rustls-pemfile", 1696 | "serde", 1697 | "serde_json", 1698 | "sha2", 1699 | "smallvec", 1700 | "thiserror", 1701 | "tokio", 1702 | "tokio-stream", 1703 | "tracing", 1704 | "url", 1705 | "webpki-roots", 1706 | ] 1707 | 1708 | [[package]] 1709 | name = "sqlx-macros" 1710 | version = "0.8.3" 1711 | source = "registry+https://github.com/rust-lang/crates.io-index" 1712 | checksum = "3112e2ad78643fef903618d78cf0aec1cb3134b019730edb039b69eaf531f310" 1713 | dependencies = [ 1714 | "proc-macro2", 1715 | "quote", 1716 | "sqlx-core", 1717 | "sqlx-macros-core", 1718 | "syn", 1719 | ] 1720 | 1721 | [[package]] 1722 | name = "sqlx-macros-core" 1723 | version = "0.8.3" 1724 | source = "registry+https://github.com/rust-lang/crates.io-index" 1725 | checksum = "4e9f90acc5ab146a99bf5061a7eb4976b573f560bc898ef3bf8435448dd5e7ad" 1726 | dependencies = [ 1727 | "dotenvy", 1728 | "either", 1729 | "heck", 1730 | "hex", 1731 | "once_cell", 1732 | "proc-macro2", 1733 | "quote", 1734 | "serde", 1735 | "serde_json", 1736 | "sha2", 1737 | "sqlx-core", 1738 | "sqlx-mysql", 1739 | "sqlx-postgres", 1740 | "sqlx-sqlite", 1741 | "syn", 1742 | "tempfile", 1743 | "tokio", 1744 | "url", 1745 | ] 1746 | 1747 | [[package]] 1748 | name = "sqlx-mysql" 1749 | version = "0.8.3" 1750 | source = "registry+https://github.com/rust-lang/crates.io-index" 1751 | checksum = "4560278f0e00ce64938540546f59f590d60beee33fffbd3b9cd47851e5fff233" 1752 | dependencies = [ 1753 | "atoi", 1754 | "base64", 1755 | "bitflags", 1756 | "byteorder", 1757 | "bytes", 1758 | "crc", 1759 | "digest", 1760 | "dotenvy", 1761 | "either", 1762 | "futures-channel", 1763 | "futures-core", 1764 | "futures-io", 1765 | "futures-util", 1766 | "generic-array", 1767 | "hex", 1768 | "hkdf", 1769 | "hmac", 1770 | "itoa", 1771 | "log", 1772 | "md-5", 1773 | "memchr", 1774 | "once_cell", 1775 | "percent-encoding", 1776 | "rand", 1777 | "rsa", 1778 | "serde", 1779 | "sha1", 1780 | "sha2", 1781 | "smallvec", 1782 | "sqlx-core", 1783 | "stringprep", 1784 | "thiserror", 1785 | "tracing", 1786 | "whoami", 1787 | ] 1788 | 1789 | [[package]] 1790 | name = "sqlx-postgres" 1791 | version = "0.8.3" 1792 | source = "registry+https://github.com/rust-lang/crates.io-index" 1793 | checksum = "c5b98a57f363ed6764d5b3a12bfedf62f07aa16e1856a7ddc2a0bb190a959613" 1794 | dependencies = [ 1795 | "atoi", 1796 | "base64", 1797 | "bitflags", 1798 | "byteorder", 1799 | "crc", 1800 | "dotenvy", 1801 | "etcetera", 1802 | "futures-channel", 1803 | "futures-core", 1804 | "futures-util", 1805 | "hex", 1806 | "hkdf", 1807 | "hmac", 1808 | "home", 1809 | "itoa", 1810 | "log", 1811 | "md-5", 1812 | "memchr", 1813 | "once_cell", 1814 | "rand", 1815 | "serde", 1816 | "serde_json", 1817 | "sha2", 1818 | "smallvec", 1819 | "sqlx-core", 1820 | "stringprep", 1821 | "thiserror", 1822 | "tracing", 1823 | "whoami", 1824 | ] 1825 | 1826 | [[package]] 1827 | name = "sqlx-sqlite" 1828 | version = "0.8.3" 1829 | source = "registry+https://github.com/rust-lang/crates.io-index" 1830 | checksum = "f85ca71d3a5b24e64e1d08dd8fe36c6c95c339a896cc33068148906784620540" 1831 | dependencies = [ 1832 | "atoi", 1833 | "flume", 1834 | "futures-channel", 1835 | "futures-core", 1836 | "futures-executor", 1837 | "futures-intrusive", 1838 | "futures-util", 1839 | "libsqlite3-sys", 1840 | "log", 1841 | "percent-encoding", 1842 | "serde", 1843 | "serde_urlencoded", 1844 | "sqlx-core", 1845 | "tracing", 1846 | "url", 1847 | ] 1848 | 1849 | [[package]] 1850 | name = "stable_deref_trait" 1851 | version = "1.2.0" 1852 | source = "registry+https://github.com/rust-lang/crates.io-index" 1853 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1854 | 1855 | [[package]] 1856 | name = "stringprep" 1857 | version = "0.1.5" 1858 | source = "registry+https://github.com/rust-lang/crates.io-index" 1859 | checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" 1860 | dependencies = [ 1861 | "unicode-bidi", 1862 | "unicode-normalization", 1863 | "unicode-properties", 1864 | ] 1865 | 1866 | [[package]] 1867 | name = "strsim" 1868 | version = "0.11.1" 1869 | source = "registry+https://github.com/rust-lang/crates.io-index" 1870 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1871 | 1872 | [[package]] 1873 | name = "subtle" 1874 | version = "2.6.1" 1875 | source = "registry+https://github.com/rust-lang/crates.io-index" 1876 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1877 | 1878 | [[package]] 1879 | name = "syn" 1880 | version = "2.0.96" 1881 | source = "registry+https://github.com/rust-lang/crates.io-index" 1882 | checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" 1883 | dependencies = [ 1884 | "proc-macro2", 1885 | "quote", 1886 | "unicode-ident", 1887 | ] 1888 | 1889 | [[package]] 1890 | name = "sync_wrapper" 1891 | version = "1.0.2" 1892 | source = "registry+https://github.com/rust-lang/crates.io-index" 1893 | checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 1894 | dependencies = [ 1895 | "futures-core", 1896 | ] 1897 | 1898 | [[package]] 1899 | name = "synstructure" 1900 | version = "0.13.1" 1901 | source = "registry+https://github.com/rust-lang/crates.io-index" 1902 | checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" 1903 | dependencies = [ 1904 | "proc-macro2", 1905 | "quote", 1906 | "syn", 1907 | ] 1908 | 1909 | [[package]] 1910 | name = "tempfile" 1911 | version = "3.15.0" 1912 | source = "registry+https://github.com/rust-lang/crates.io-index" 1913 | checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" 1914 | dependencies = [ 1915 | "cfg-if", 1916 | "fastrand", 1917 | "getrandom", 1918 | "once_cell", 1919 | "rustix", 1920 | "windows-sys 0.59.0", 1921 | ] 1922 | 1923 | [[package]] 1924 | name = "thiserror" 1925 | version = "2.0.11" 1926 | source = "registry+https://github.com/rust-lang/crates.io-index" 1927 | checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" 1928 | dependencies = [ 1929 | "thiserror-impl", 1930 | ] 1931 | 1932 | [[package]] 1933 | name = "thiserror-impl" 1934 | version = "2.0.11" 1935 | source = "registry+https://github.com/rust-lang/crates.io-index" 1936 | checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" 1937 | dependencies = [ 1938 | "proc-macro2", 1939 | "quote", 1940 | "syn", 1941 | ] 1942 | 1943 | [[package]] 1944 | name = "tinystr" 1945 | version = "0.7.6" 1946 | source = "registry+https://github.com/rust-lang/crates.io-index" 1947 | checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" 1948 | dependencies = [ 1949 | "displaydoc", 1950 | "zerovec", 1951 | ] 1952 | 1953 | [[package]] 1954 | name = "tinyvec" 1955 | version = "1.8.1" 1956 | source = "registry+https://github.com/rust-lang/crates.io-index" 1957 | checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" 1958 | dependencies = [ 1959 | "tinyvec_macros", 1960 | ] 1961 | 1962 | [[package]] 1963 | name = "tinyvec_macros" 1964 | version = "0.1.1" 1965 | source = "registry+https://github.com/rust-lang/crates.io-index" 1966 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1967 | 1968 | [[package]] 1969 | name = "tokio" 1970 | version = "1.43.0" 1971 | source = "registry+https://github.com/rust-lang/crates.io-index" 1972 | checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" 1973 | dependencies = [ 1974 | "backtrace", 1975 | "bytes", 1976 | "libc", 1977 | "mio", 1978 | "pin-project-lite", 1979 | "socket2", 1980 | "tokio-macros", 1981 | "windows-sys 0.52.0", 1982 | ] 1983 | 1984 | [[package]] 1985 | name = "tokio-macros" 1986 | version = "2.5.0" 1987 | source = "registry+https://github.com/rust-lang/crates.io-index" 1988 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 1989 | dependencies = [ 1990 | "proc-macro2", 1991 | "quote", 1992 | "syn", 1993 | ] 1994 | 1995 | [[package]] 1996 | name = "tokio-rustls" 1997 | version = "0.26.1" 1998 | source = "registry+https://github.com/rust-lang/crates.io-index" 1999 | checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" 2000 | dependencies = [ 2001 | "rustls", 2002 | "tokio", 2003 | ] 2004 | 2005 | [[package]] 2006 | name = "tokio-stream" 2007 | version = "0.1.17" 2008 | source = "registry+https://github.com/rust-lang/crates.io-index" 2009 | checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" 2010 | dependencies = [ 2011 | "futures-core", 2012 | "pin-project-lite", 2013 | "tokio", 2014 | ] 2015 | 2016 | [[package]] 2017 | name = "tokio-util" 2018 | version = "0.7.13" 2019 | source = "registry+https://github.com/rust-lang/crates.io-index" 2020 | checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" 2021 | dependencies = [ 2022 | "bytes", 2023 | "futures-core", 2024 | "futures-sink", 2025 | "pin-project-lite", 2026 | "tokio", 2027 | ] 2028 | 2029 | [[package]] 2030 | name = "tower" 2031 | version = "0.5.2" 2032 | source = "registry+https://github.com/rust-lang/crates.io-index" 2033 | checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 2034 | dependencies = [ 2035 | "futures-core", 2036 | "futures-util", 2037 | "pin-project-lite", 2038 | "sync_wrapper", 2039 | "tokio", 2040 | "tower-layer", 2041 | "tower-service", 2042 | ] 2043 | 2044 | [[package]] 2045 | name = "tower-layer" 2046 | version = "0.3.3" 2047 | source = "registry+https://github.com/rust-lang/crates.io-index" 2048 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 2049 | 2050 | [[package]] 2051 | name = "tower-service" 2052 | version = "0.3.3" 2053 | source = "registry+https://github.com/rust-lang/crates.io-index" 2054 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 2055 | 2056 | [[package]] 2057 | name = "tracing" 2058 | version = "0.1.41" 2059 | source = "registry+https://github.com/rust-lang/crates.io-index" 2060 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 2061 | dependencies = [ 2062 | "log", 2063 | "pin-project-lite", 2064 | "tracing-attributes", 2065 | "tracing-core", 2066 | ] 2067 | 2068 | [[package]] 2069 | name = "tracing-attributes" 2070 | version = "0.1.28" 2071 | source = "registry+https://github.com/rust-lang/crates.io-index" 2072 | checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" 2073 | dependencies = [ 2074 | "proc-macro2", 2075 | "quote", 2076 | "syn", 2077 | ] 2078 | 2079 | [[package]] 2080 | name = "tracing-core" 2081 | version = "0.1.33" 2082 | source = "registry+https://github.com/rust-lang/crates.io-index" 2083 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 2084 | dependencies = [ 2085 | "once_cell", 2086 | ] 2087 | 2088 | [[package]] 2089 | name = "try-lock" 2090 | version = "0.2.5" 2091 | source = "registry+https://github.com/rust-lang/crates.io-index" 2092 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 2093 | 2094 | [[package]] 2095 | name = "typenum" 2096 | version = "1.17.0" 2097 | source = "registry+https://github.com/rust-lang/crates.io-index" 2098 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 2099 | 2100 | [[package]] 2101 | name = "unicode-bidi" 2102 | version = "0.3.18" 2103 | source = "registry+https://github.com/rust-lang/crates.io-index" 2104 | checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" 2105 | 2106 | [[package]] 2107 | name = "unicode-ident" 2108 | version = "1.0.14" 2109 | source = "registry+https://github.com/rust-lang/crates.io-index" 2110 | checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" 2111 | 2112 | [[package]] 2113 | name = "unicode-normalization" 2114 | version = "0.1.24" 2115 | source = "registry+https://github.com/rust-lang/crates.io-index" 2116 | checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" 2117 | dependencies = [ 2118 | "tinyvec", 2119 | ] 2120 | 2121 | [[package]] 2122 | name = "unicode-properties" 2123 | version = "0.1.3" 2124 | source = "registry+https://github.com/rust-lang/crates.io-index" 2125 | checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" 2126 | 2127 | [[package]] 2128 | name = "unicode-width" 2129 | version = "0.2.0" 2130 | source = "registry+https://github.com/rust-lang/crates.io-index" 2131 | checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" 2132 | 2133 | [[package]] 2134 | name = "untrusted" 2135 | version = "0.9.0" 2136 | source = "registry+https://github.com/rust-lang/crates.io-index" 2137 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 2138 | 2139 | [[package]] 2140 | name = "url" 2141 | version = "2.5.4" 2142 | source = "registry+https://github.com/rust-lang/crates.io-index" 2143 | checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 2144 | dependencies = [ 2145 | "form_urlencoded", 2146 | "idna", 2147 | "percent-encoding", 2148 | ] 2149 | 2150 | [[package]] 2151 | name = "utf16_iter" 2152 | version = "1.0.5" 2153 | source = "registry+https://github.com/rust-lang/crates.io-index" 2154 | checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" 2155 | 2156 | [[package]] 2157 | name = "utf8_iter" 2158 | version = "1.0.4" 2159 | source = "registry+https://github.com/rust-lang/crates.io-index" 2160 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 2161 | 2162 | [[package]] 2163 | name = "utf8parse" 2164 | version = "0.2.2" 2165 | source = "registry+https://github.com/rust-lang/crates.io-index" 2166 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 2167 | 2168 | [[package]] 2169 | name = "vcpkg" 2170 | version = "0.2.15" 2171 | source = "registry+https://github.com/rust-lang/crates.io-index" 2172 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 2173 | 2174 | [[package]] 2175 | name = "version_check" 2176 | version = "0.9.5" 2177 | source = "registry+https://github.com/rust-lang/crates.io-index" 2178 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 2179 | 2180 | [[package]] 2181 | name = "want" 2182 | version = "0.3.1" 2183 | source = "registry+https://github.com/rust-lang/crates.io-index" 2184 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 2185 | dependencies = [ 2186 | "try-lock", 2187 | ] 2188 | 2189 | [[package]] 2190 | name = "wasi" 2191 | version = "0.11.0+wasi-snapshot-preview1" 2192 | source = "registry+https://github.com/rust-lang/crates.io-index" 2193 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2194 | 2195 | [[package]] 2196 | name = "wasite" 2197 | version = "0.1.0" 2198 | source = "registry+https://github.com/rust-lang/crates.io-index" 2199 | checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" 2200 | 2201 | [[package]] 2202 | name = "wasm-bindgen" 2203 | version = "0.2.100" 2204 | source = "registry+https://github.com/rust-lang/crates.io-index" 2205 | checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" 2206 | dependencies = [ 2207 | "cfg-if", 2208 | "once_cell", 2209 | "rustversion", 2210 | "wasm-bindgen-macro", 2211 | ] 2212 | 2213 | [[package]] 2214 | name = "wasm-bindgen-backend" 2215 | version = "0.2.100" 2216 | source = "registry+https://github.com/rust-lang/crates.io-index" 2217 | checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" 2218 | dependencies = [ 2219 | "bumpalo", 2220 | "log", 2221 | "proc-macro2", 2222 | "quote", 2223 | "syn", 2224 | "wasm-bindgen-shared", 2225 | ] 2226 | 2227 | [[package]] 2228 | name = "wasm-bindgen-futures" 2229 | version = "0.4.50" 2230 | source = "registry+https://github.com/rust-lang/crates.io-index" 2231 | checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" 2232 | dependencies = [ 2233 | "cfg-if", 2234 | "js-sys", 2235 | "once_cell", 2236 | "wasm-bindgen", 2237 | "web-sys", 2238 | ] 2239 | 2240 | [[package]] 2241 | name = "wasm-bindgen-macro" 2242 | version = "0.2.100" 2243 | source = "registry+https://github.com/rust-lang/crates.io-index" 2244 | checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" 2245 | dependencies = [ 2246 | "quote", 2247 | "wasm-bindgen-macro-support", 2248 | ] 2249 | 2250 | [[package]] 2251 | name = "wasm-bindgen-macro-support" 2252 | version = "0.2.100" 2253 | source = "registry+https://github.com/rust-lang/crates.io-index" 2254 | checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" 2255 | dependencies = [ 2256 | "proc-macro2", 2257 | "quote", 2258 | "syn", 2259 | "wasm-bindgen-backend", 2260 | "wasm-bindgen-shared", 2261 | ] 2262 | 2263 | [[package]] 2264 | name = "wasm-bindgen-shared" 2265 | version = "0.2.100" 2266 | source = "registry+https://github.com/rust-lang/crates.io-index" 2267 | checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" 2268 | dependencies = [ 2269 | "unicode-ident", 2270 | ] 2271 | 2272 | [[package]] 2273 | name = "web-sys" 2274 | version = "0.3.77" 2275 | source = "registry+https://github.com/rust-lang/crates.io-index" 2276 | checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" 2277 | dependencies = [ 2278 | "js-sys", 2279 | "wasm-bindgen", 2280 | ] 2281 | 2282 | [[package]] 2283 | name = "web-time" 2284 | version = "1.1.0" 2285 | source = "registry+https://github.com/rust-lang/crates.io-index" 2286 | checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 2287 | dependencies = [ 2288 | "js-sys", 2289 | "wasm-bindgen", 2290 | ] 2291 | 2292 | [[package]] 2293 | name = "webpki-roots" 2294 | version = "0.26.7" 2295 | source = "registry+https://github.com/rust-lang/crates.io-index" 2296 | checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" 2297 | dependencies = [ 2298 | "rustls-pki-types", 2299 | ] 2300 | 2301 | [[package]] 2302 | name = "whoami" 2303 | version = "1.5.2" 2304 | source = "registry+https://github.com/rust-lang/crates.io-index" 2305 | checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" 2306 | dependencies = [ 2307 | "redox_syscall", 2308 | "wasite", 2309 | ] 2310 | 2311 | [[package]] 2312 | name = "windows-registry" 2313 | version = "0.2.0" 2314 | source = "registry+https://github.com/rust-lang/crates.io-index" 2315 | checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" 2316 | dependencies = [ 2317 | "windows-result", 2318 | "windows-strings", 2319 | "windows-targets 0.52.6", 2320 | ] 2321 | 2322 | [[package]] 2323 | name = "windows-result" 2324 | version = "0.2.0" 2325 | source = "registry+https://github.com/rust-lang/crates.io-index" 2326 | checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" 2327 | dependencies = [ 2328 | "windows-targets 0.52.6", 2329 | ] 2330 | 2331 | [[package]] 2332 | name = "windows-strings" 2333 | version = "0.1.0" 2334 | source = "registry+https://github.com/rust-lang/crates.io-index" 2335 | checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" 2336 | dependencies = [ 2337 | "windows-result", 2338 | "windows-targets 0.52.6", 2339 | ] 2340 | 2341 | [[package]] 2342 | name = "windows-sys" 2343 | version = "0.48.0" 2344 | source = "registry+https://github.com/rust-lang/crates.io-index" 2345 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 2346 | dependencies = [ 2347 | "windows-targets 0.48.5", 2348 | ] 2349 | 2350 | [[package]] 2351 | name = "windows-sys" 2352 | version = "0.52.0" 2353 | source = "registry+https://github.com/rust-lang/crates.io-index" 2354 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2355 | dependencies = [ 2356 | "windows-targets 0.52.6", 2357 | ] 2358 | 2359 | [[package]] 2360 | name = "windows-sys" 2361 | version = "0.59.0" 2362 | source = "registry+https://github.com/rust-lang/crates.io-index" 2363 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2364 | dependencies = [ 2365 | "windows-targets 0.52.6", 2366 | ] 2367 | 2368 | [[package]] 2369 | name = "windows-targets" 2370 | version = "0.48.5" 2371 | source = "registry+https://github.com/rust-lang/crates.io-index" 2372 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2373 | dependencies = [ 2374 | "windows_aarch64_gnullvm 0.48.5", 2375 | "windows_aarch64_msvc 0.48.5", 2376 | "windows_i686_gnu 0.48.5", 2377 | "windows_i686_msvc 0.48.5", 2378 | "windows_x86_64_gnu 0.48.5", 2379 | "windows_x86_64_gnullvm 0.48.5", 2380 | "windows_x86_64_msvc 0.48.5", 2381 | ] 2382 | 2383 | [[package]] 2384 | name = "windows-targets" 2385 | version = "0.52.6" 2386 | source = "registry+https://github.com/rust-lang/crates.io-index" 2387 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2388 | dependencies = [ 2389 | "windows_aarch64_gnullvm 0.52.6", 2390 | "windows_aarch64_msvc 0.52.6", 2391 | "windows_i686_gnu 0.52.6", 2392 | "windows_i686_gnullvm", 2393 | "windows_i686_msvc 0.52.6", 2394 | "windows_x86_64_gnu 0.52.6", 2395 | "windows_x86_64_gnullvm 0.52.6", 2396 | "windows_x86_64_msvc 0.52.6", 2397 | ] 2398 | 2399 | [[package]] 2400 | name = "windows_aarch64_gnullvm" 2401 | version = "0.48.5" 2402 | source = "registry+https://github.com/rust-lang/crates.io-index" 2403 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2404 | 2405 | [[package]] 2406 | name = "windows_aarch64_gnullvm" 2407 | version = "0.52.6" 2408 | source = "registry+https://github.com/rust-lang/crates.io-index" 2409 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2410 | 2411 | [[package]] 2412 | name = "windows_aarch64_msvc" 2413 | version = "0.48.5" 2414 | source = "registry+https://github.com/rust-lang/crates.io-index" 2415 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2416 | 2417 | [[package]] 2418 | name = "windows_aarch64_msvc" 2419 | version = "0.52.6" 2420 | source = "registry+https://github.com/rust-lang/crates.io-index" 2421 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2422 | 2423 | [[package]] 2424 | name = "windows_i686_gnu" 2425 | version = "0.48.5" 2426 | source = "registry+https://github.com/rust-lang/crates.io-index" 2427 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2428 | 2429 | [[package]] 2430 | name = "windows_i686_gnu" 2431 | version = "0.52.6" 2432 | source = "registry+https://github.com/rust-lang/crates.io-index" 2433 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2434 | 2435 | [[package]] 2436 | name = "windows_i686_gnullvm" 2437 | version = "0.52.6" 2438 | source = "registry+https://github.com/rust-lang/crates.io-index" 2439 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2440 | 2441 | [[package]] 2442 | name = "windows_i686_msvc" 2443 | version = "0.48.5" 2444 | source = "registry+https://github.com/rust-lang/crates.io-index" 2445 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2446 | 2447 | [[package]] 2448 | name = "windows_i686_msvc" 2449 | version = "0.52.6" 2450 | source = "registry+https://github.com/rust-lang/crates.io-index" 2451 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2452 | 2453 | [[package]] 2454 | name = "windows_x86_64_gnu" 2455 | version = "0.48.5" 2456 | source = "registry+https://github.com/rust-lang/crates.io-index" 2457 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2458 | 2459 | [[package]] 2460 | name = "windows_x86_64_gnu" 2461 | version = "0.52.6" 2462 | source = "registry+https://github.com/rust-lang/crates.io-index" 2463 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2464 | 2465 | [[package]] 2466 | name = "windows_x86_64_gnullvm" 2467 | version = "0.48.5" 2468 | source = "registry+https://github.com/rust-lang/crates.io-index" 2469 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2470 | 2471 | [[package]] 2472 | name = "windows_x86_64_gnullvm" 2473 | version = "0.52.6" 2474 | source = "registry+https://github.com/rust-lang/crates.io-index" 2475 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2476 | 2477 | [[package]] 2478 | name = "windows_x86_64_msvc" 2479 | version = "0.48.5" 2480 | source = "registry+https://github.com/rust-lang/crates.io-index" 2481 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2482 | 2483 | [[package]] 2484 | name = "windows_x86_64_msvc" 2485 | version = "0.52.6" 2486 | source = "registry+https://github.com/rust-lang/crates.io-index" 2487 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2488 | 2489 | [[package]] 2490 | name = "write16" 2491 | version = "1.0.0" 2492 | source = "registry+https://github.com/rust-lang/crates.io-index" 2493 | checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" 2494 | 2495 | [[package]] 2496 | name = "writeable" 2497 | version = "0.5.5" 2498 | source = "registry+https://github.com/rust-lang/crates.io-index" 2499 | checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" 2500 | 2501 | [[package]] 2502 | name = "yoke" 2503 | version = "0.7.5" 2504 | source = "registry+https://github.com/rust-lang/crates.io-index" 2505 | checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" 2506 | dependencies = [ 2507 | "serde", 2508 | "stable_deref_trait", 2509 | "yoke-derive", 2510 | "zerofrom", 2511 | ] 2512 | 2513 | [[package]] 2514 | name = "yoke-derive" 2515 | version = "0.7.5" 2516 | source = "registry+https://github.com/rust-lang/crates.io-index" 2517 | checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" 2518 | dependencies = [ 2519 | "proc-macro2", 2520 | "quote", 2521 | "syn", 2522 | "synstructure", 2523 | ] 2524 | 2525 | [[package]] 2526 | name = "zerocopy" 2527 | version = "0.7.35" 2528 | source = "registry+https://github.com/rust-lang/crates.io-index" 2529 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 2530 | dependencies = [ 2531 | "byteorder", 2532 | "zerocopy-derive", 2533 | ] 2534 | 2535 | [[package]] 2536 | name = "zerocopy-derive" 2537 | version = "0.7.35" 2538 | source = "registry+https://github.com/rust-lang/crates.io-index" 2539 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 2540 | dependencies = [ 2541 | "proc-macro2", 2542 | "quote", 2543 | "syn", 2544 | ] 2545 | 2546 | [[package]] 2547 | name = "zerofrom" 2548 | version = "0.1.5" 2549 | source = "registry+https://github.com/rust-lang/crates.io-index" 2550 | checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" 2551 | dependencies = [ 2552 | "zerofrom-derive", 2553 | ] 2554 | 2555 | [[package]] 2556 | name = "zerofrom-derive" 2557 | version = "0.1.5" 2558 | source = "registry+https://github.com/rust-lang/crates.io-index" 2559 | checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" 2560 | dependencies = [ 2561 | "proc-macro2", 2562 | "quote", 2563 | "syn", 2564 | "synstructure", 2565 | ] 2566 | 2567 | [[package]] 2568 | name = "zeroize" 2569 | version = "1.8.1" 2570 | source = "registry+https://github.com/rust-lang/crates.io-index" 2571 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 2572 | 2573 | [[package]] 2574 | name = "zerovec" 2575 | version = "0.10.4" 2576 | source = "registry+https://github.com/rust-lang/crates.io-index" 2577 | checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" 2578 | dependencies = [ 2579 | "yoke", 2580 | "zerofrom", 2581 | "zerovec-derive", 2582 | ] 2583 | 2584 | [[package]] 2585 | name = "zerovec-derive" 2586 | version = "0.10.3" 2587 | source = "registry+https://github.com/rust-lang/crates.io-index" 2588 | checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" 2589 | dependencies = [ 2590 | "proc-macro2", 2591 | "quote", 2592 | "syn", 2593 | ] 2594 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ecomdev-download-magento-images" 3 | description = "CLI tool to download images from a store based on its database table" 4 | version = "0.1.0" 5 | edition = "2021" 6 | authors = ["Ivan Chepurnyi "] 7 | repository = "https://github.com/EcomDev/download-magento-images-rs" 8 | license = "MIT" 9 | rust-version = "1.80.0" 10 | 11 | [dependencies] 12 | sqlx = { version = "0.8.2", features = ["mysql", "runtime-tokio-rustls", "macros"] } 13 | tokio = { version = "1", features = ["macros"] } 14 | reqwest = { version = "0.12.4", default-features = false, features = ["h2", "rustls-tls-webpki-roots", "brotli", "gzip"]} 15 | indicatif = "0.17.8" 16 | clap = { version = "4", features = ["derive"] } 17 | anyhow = { version = "1" } 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 EcomDev B.V. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Media Downloader Tool 2 | 3 | The Media Downloader Tool is a Rust-based application for downloading media files from a remote source while utilizing batched processing and high concurrency. This tool supports downloading large volumes of media efficiently and includes progress tracking. 4 | 5 | ## Features 6 | 7 | - **Batch Processing:** Efficiently fetches and processes media in configurable batches. 8 | - **Concurrency Control:** Controls the number of concurrent download clients. 9 | - **Progress Tracking:** Displays a progress bar for the media download process. 10 | - **Error Handling:** Reports failed, skipped, and completed downloads. 11 | - **Database Integration:** Reads media data from a MySQL database table. 12 | 13 | ## Prerequisites 14 | 15 | Before starting, ensure you have the following installed on your machine: 16 | 17 | - [Rust](https://www.rust-lang.org/tools/install) (version `1.83.0` or later is recommended) 18 | - Magento database with the necessary table (`catalog_product_entity_media_gallery`) 19 | 20 | ## Installation 21 | 22 | 23 | 1. Clone this repository: 24 | ```bash 25 | git clone 26 | cd 27 | ``` 28 | 29 | 2. Build the project: 30 | ```bash 31 | cargo build --release 32 | ``` 33 | 34 | 3. Set up your MySQL database connection and ensure the `catalog_product_entity_media_gallery` table is populated with entries. 35 | 36 | ## Usage 37 | 38 | Run the tool with the following command: 39 | 40 | ```bash 41 | Usage: ecomdev-download-magento-images [OPTIONS] 42 | 43 | Arguments: 44 | Base URL for media download 45 | 46 | Options: 47 | -p, --base-path Directory path [default: pub/media] 48 | -u, --user-agent User agent [default: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0"] 49 | -c, --max-clients Max number of clients to create for downloading [default: 100] 50 | -b, --batch-size Max number of items to fetch per batch [default: 10000] 51 | -d, --database-url Database URL to use of connection [default: mysql://magento:magento@localhost/magento] 52 | -h, --help Print help 53 | ``` 54 | 55 | ## Development 56 | 57 | To develop or test this tool, follow these steps: 58 | 59 | 1. Ensure `sqlx` knows about your database schema by running: 60 | ```bash 61 | export DATABASE_URL=mysql://user:password@localhost/db 62 | cargo sqlx prepare -- --lib 63 | ``` 64 | 65 | 2. Run in development mode: 66 | ```bash 67 | cargo run -- [OPTIONS] 68 | ``` 69 | 70 | 3. Test the application with mock data or a test database. 71 | 72 | ## Contributing 73 | 74 | Contributions are welcome! Please follow these steps: 75 | 76 | 1. Fork this repository. 77 | 2. Create a branch with your feature or fix: 78 | ```bash 79 | git checkout -b feature/my-feature 80 | ``` 81 | 3. Commit your changes and push your branch: 82 | ```bash 83 | git push origin feature/my-feature 84 | ``` 85 | 4. Open a pull request for review. 86 | 87 | ## License 88 | 89 | This project is licensed under the MIT License. See the `LICENSE` file for details. -------------------------------------------------------------------------------- /deny.toml: -------------------------------------------------------------------------------- 1 | # This section is considered when running `cargo deny check advisories` 2 | # More documentation for the advisories section can be found here: 3 | # https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html 4 | [advisories] 5 | 6 | # This section is considered when running `cargo deny check licenses` 7 | # More documentation for the licenses section can be found here: 8 | # https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html 9 | [licenses] 10 | unused-allowed-license = "warn" 11 | allow = [ 12 | "MIT", 13 | "Apache-2.0", 14 | "Unicode-3.0", 15 | "ISC", 16 | "CC0-1.0", 17 | "BSD-3-Clause", 18 | "OpenSSL", 19 | "Zlib" 20 | ] 21 | confidence-threshold = 0.8 22 | 23 | [[licenses.clarify]] 24 | crate = "ring" 25 | expression = "MIT AND ISC AND OpenSSL" 26 | license-files = [ 27 | { path = "LICENSE", hash = 0xbd0eed23 } 28 | ] 29 | 30 | 31 | [bans] 32 | multiple-versions = "warn" 33 | wildcards = "allow" 34 | highlight = "all" 35 | workspace-default-features = "allow" 36 | external-default-features = "allow" 37 | allow = [] 38 | deny = [] 39 | skip = [] 40 | skip-tree = [] 41 | 42 | 43 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | mysql: 3 | image: ghcr.io/ecomdev/testcontainer-magento-data/mysql:latest-sampledata 4 | ports: 5 | - 3306:3306 -------------------------------------------------------------------------------- /src/http.rs: -------------------------------------------------------------------------------- 1 | use reqwest::Client; 2 | use std::path::{Path, PathBuf}; 3 | use std::sync::Arc; 4 | use tokio::fs::{create_dir_all, try_exists, File}; 5 | use tokio::io::AsyncWriteExt; 6 | use tokio::task::JoinSet; 7 | 8 | #[derive(Debug, PartialEq)] 9 | pub(crate) enum BaseUrl { 10 | External(String), 11 | MagentoMedia(String), 12 | } 13 | 14 | impl From for BaseUrl 15 | where 16 | T: AsRef, 17 | { 18 | fn from(v: T) -> Self { 19 | let v = v.as_ref().trim_end_matches('/'); 20 | 21 | if v.ends_with("/media") { 22 | return BaseUrl::MagentoMedia(v.to_string()); 23 | } 24 | 25 | BaseUrl::External(v.to_string()) 26 | } 27 | } 28 | 29 | pub(crate) struct DownloadConfig { 30 | pub base_url: BaseUrl, 31 | pub base_path: String, 32 | pub user_agent: String, 33 | pub clients: u16, 34 | } 35 | 36 | pub(crate) trait DownloadProgress { 37 | fn completed(&mut self, image: String); 38 | 39 | fn error(&mut self, image: String); 40 | 41 | fn skipped(&mut self, image: String); 42 | } 43 | 44 | enum TaskResult { 45 | Success(String, Client), 46 | Skipped(String, Client), 47 | Error(String, Client), 48 | } 49 | 50 | pub(crate) struct HttpPool { 51 | pool: Vec, 52 | tasks: JoinSet, 53 | } 54 | 55 | impl HttpPool { 56 | pub(crate) fn new() -> Self { 57 | Self { 58 | pool: Vec::new(), 59 | tasks: JoinSet::new(), 60 | } 61 | } 62 | 63 | pub(crate) async fn download( 64 | &mut self, 65 | images: impl Iterator, 66 | progress: &mut impl DownloadProgress, 67 | config: Arc, 68 | ) -> Result<(), anyhow::Error> { 69 | for image in images { 70 | if config.is_full((self.tasks.len() + self.pool.len()) as u16) { 71 | match self.tasks.join_next().await { 72 | Some(Ok(TaskResult::Success(image, client))) => { 73 | progress.completed(image); 74 | self.pool.push(client); 75 | } 76 | Some(Ok(TaskResult::Error(image, client))) => { 77 | progress.error(image); 78 | self.pool.push(client); 79 | } 80 | Some(Ok(TaskResult::Skipped(image, client))) => { 81 | progress.skipped(image); 82 | self.pool.push(client); 83 | } 84 | _ => {} 85 | } 86 | } 87 | 88 | let client = match self.pool.pop() { 89 | Some(client) => client, 90 | None => Client::builder().user_agent(&config.user_agent).build()?, 91 | }; 92 | 93 | self.tasks.spawn({ 94 | let config = config.clone(); 95 | async move { 96 | let image_path = Path::new(&image); 97 | let download_url = config.image_url(image_path); 98 | let file_path = config.file_path(image_path); 99 | 100 | if try_exists(&file_path).await.unwrap_or(false) { 101 | return TaskResult::Skipped(image, client); 102 | } 103 | 104 | let mut response = match client.get(download_url).send().await { 105 | Ok(response) => response, 106 | Err(_) => return TaskResult::Error(image, client), 107 | }; 108 | 109 | let status = response.status(); 110 | if !status.is_success() { 111 | return TaskResult::Error(format!("{image} - {}", status.as_str()), client); 112 | } 113 | 114 | if let Some(path) = file_path.parent() { 115 | if create_dir_all(path).await.is_err() { 116 | return TaskResult::Error(image, client); 117 | } 118 | } 119 | 120 | let mut file = match File::create(&file_path).await { 121 | Ok(file) => file, 122 | Err(_) => return TaskResult::Error(image, client), 123 | }; 124 | 125 | while let Ok(Some(chunk)) = response.chunk().await { 126 | if (file.write_all(chunk.as_ref()).await).is_err() { 127 | return TaskResult::Error(image, client); 128 | } 129 | } 130 | 131 | TaskResult::Success(image, client) 132 | } 133 | }); 134 | } 135 | 136 | Ok(()) 137 | } 138 | } 139 | 140 | fn relative_path(image: &Path) -> PathBuf { 141 | let mut path = PathBuf::from("catalog/product"); 142 | path.push(image); 143 | path 144 | } 145 | 146 | impl DownloadConfig { 147 | fn is_full(&self, current_size: u16) -> bool { 148 | self.clients >= current_size 149 | } 150 | 151 | fn image_url(&self, image: &Path) -> String { 152 | let (base_url, path) = match &self.base_url { 153 | BaseUrl::External(base_url) => ( 154 | base_url, 155 | PathBuf::from(image.file_name().unwrap_or_default()), 156 | ), 157 | BaseUrl::MagentoMedia(base_url) => (base_url, relative_path(image)), 158 | }; 159 | 160 | format!("{base_url}/{}", path.to_string_lossy()) 161 | } 162 | 163 | fn file_path(&self, image: &Path) -> PathBuf { 164 | let mut path_buf = PathBuf::from(&self.base_path); 165 | path_buf.push(relative_path(image)); 166 | path_buf 167 | } 168 | } 169 | 170 | #[cfg(test)] 171 | mod tests { 172 | use super::*; 173 | 174 | #[test] 175 | fn creates_base_url_from_string_as_relative_path() { 176 | let base_url: BaseUrl = "http://some-magento.com/media/".into(); 177 | 178 | assert_eq!( 179 | BaseUrl::MagentoMedia("http://some-magento.com/media".into()), 180 | base_url 181 | ); 182 | } 183 | 184 | #[test] 185 | fn creates_base_url_as_external_when_no_media_path_exists() { 186 | let base_url: BaseUrl = "http://some-magento.com/test-folder/".into(); 187 | 188 | assert_eq!( 189 | BaseUrl::External("http://some-magento.com/test-folder".into()), 190 | base_url 191 | ); 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | mod http; 2 | 3 | use crate::http::{DownloadConfig, DownloadProgress, HttpPool}; 4 | use clap::Parser; 5 | use indicatif::ProgressBar; 6 | use sqlx::{Connection, MySqlConnection}; 7 | use std::sync::Arc; 8 | 9 | #[derive(Parser)] 10 | struct Options { 11 | /// Base URL for media download 12 | base_url: String, 13 | /// Directory path 14 | #[arg(short = 'p', long, default_value = "pub/media")] 15 | base_path: String, 16 | 17 | /// User agent 18 | #[arg( 19 | short = 'u', 20 | long, 21 | default_value = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0" 22 | )] 23 | user_agent: String, 24 | 25 | /// Max number of clients to create for downloading 26 | #[arg(short = 'c', long, default_value_t = 100)] 27 | max_clients: u16, 28 | 29 | /// Max number of items to fetch per batch 30 | #[arg(short = 'b', long, default_value_t = 10000)] 31 | batch_size: u16, 32 | 33 | #[arg( 34 | short = 'd', 35 | long, 36 | default_value = "mysql://magento:magento@localhost/magento" 37 | )] 38 | /// Database URL to use of connection 39 | database_url: String, 40 | } 41 | 42 | async fn total(connection: &mut MySqlConnection) -> sqlx::Result { 43 | #[derive(sqlx::Type)] 44 | struct Total { 45 | total: i64, 46 | } 47 | 48 | let query = sqlx::query_as!( 49 | Total, 50 | "SELECT COUNT(*) as total FROM catalog_product_entity_media_gallery" 51 | ); 52 | 53 | Ok(query.fetch_one(connection).await?.total as u64) 54 | } 55 | 56 | async fn ranges( 57 | connection: &mut MySqlConnection, 58 | batch_size: u16, 59 | ) -> sqlx::Result> { 60 | #[derive(sqlx::Type)] 61 | struct MinMax { 62 | min: i64, 63 | max: i64, 64 | } 65 | 66 | let query = sqlx::query_as!( 67 | MinMax, 68 | "SELECT MIN(value_id) as `min!`, MAX(value_id) as `max!` FROM catalog_product_entity_media_gallery GROUP BY CEIL(value_id / ?)", 69 | batch_size 70 | ); 71 | 72 | Ok(query 73 | .fetch_all(connection) 74 | .await? 75 | .into_iter() 76 | .map(|item| (item.min as u64, item.max as u64)) 77 | .collect()) 78 | } 79 | 80 | impl DownloadProgress for ProgressBar { 81 | fn completed(&mut self, image: String) { 82 | self.inc(1); 83 | self.println(format!("Completed downloading {image}")) 84 | } 85 | 86 | fn error(&mut self, image: String) { 87 | self.inc(1); 88 | self.println(format!("Failed to download: {image}")); 89 | } 90 | 91 | fn skipped(&mut self, image: String) { 92 | self.inc(1); 93 | self.println(format!("Skipped as file exists: {image}")); 94 | } 95 | } 96 | 97 | #[tokio::main(flavor = "current_thread")] 98 | async fn main() -> anyhow::Result<()> { 99 | let options = Options::try_parse()?; 100 | let mut connection = MySqlConnection::connect(&options.database_url).await?; 101 | let mut http = HttpPool::new(); 102 | let mut progress_bar = ProgressBar::new(total(&mut connection).await?); 103 | 104 | let download_config = Arc::new(DownloadConfig { 105 | base_url: options.base_url.into(), 106 | base_path: options.base_path, 107 | user_agent: options.user_agent, 108 | clients: options.max_clients, 109 | }); 110 | 111 | struct Image { 112 | value: String, 113 | } 114 | 115 | for (min, max) in ranges(&mut connection, options.batch_size).await? { 116 | let query = sqlx::query_as!( 117 | Image, 118 | "SELECT value as `value!` FROM catalog_product_entity_media_gallery WHERE value_id BETWEEN ? AND ?", 119 | min, 120 | max 121 | ); 122 | 123 | let images = query 124 | .fetch_all(&mut connection) 125 | .await? 126 | .into_iter() 127 | .map(|v| v.value); 128 | http.download(images, &mut progress_bar, download_config.clone()) 129 | .await? 130 | } 131 | 132 | progress_bar.finish(); 133 | 134 | Ok(()) 135 | } 136 | --------------------------------------------------------------------------------