mirror of
https://github.com/julyx10/lap.git
synced 2026-10-02 01:54:57 +08:00
Add Windows ARM 64 Native Build Support (#85)
* [CI] Add Windows ARM 64 GitHub builds * Use a patched generator-rs for Windows ARM support * Fix download url for ffmpeg on ARM64 * Replace reversegeocoder with more multi platform compatible rstar * [CI] Point back to official ffmpeg repo * Clear article bundle cache for pr linux and mac builds --------- Co-authored-by: Joseph Gershgorin <jgershgorin@biocentury.com>
This commit is contained in:
co-authored by
Joseph Gershgorin
parent
bb62225a44
commit
9774293b95
@@ -108,6 +108,10 @@ jobs:
|
||||
shell: bash
|
||||
run: bash scripts/download_models.sh
|
||||
|
||||
- name: Clear cached macOS bundle artifacts
|
||||
shell: bash
|
||||
run: rm -rf "src-tauri/target/${{ matrix.target }}/release/bundle"
|
||||
|
||||
- name: Build and Sign
|
||||
uses: tauri-apps/tauri-action@v0.5
|
||||
env:
|
||||
@@ -181,7 +185,19 @@ jobs:
|
||||
if: |
|
||||
(github.event_name == 'workflow_dispatch' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'windows')) ||
|
||||
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
|
||||
runs-on: windows-latest
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: x64
|
||||
runner: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
msvc_arch: x64
|
||||
- arch: arm64
|
||||
runner: windows-11-arm
|
||||
target: aarch64-pc-windows-msvc
|
||||
msvc_arch: arm64
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -209,14 +225,14 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: windows-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
key: windows-${{ matrix.arch }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
windows-pnpm-store-
|
||||
windows-${{ matrix.arch }}-pnpm-store-
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: x86_64-pc-windows-msvc
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- name: Cache Rust dependencies
|
||||
uses: actions/cache@v4
|
||||
@@ -227,9 +243,9 @@ jobs:
|
||||
~\.cargo\registry\cache\
|
||||
~\.cargo\git\db\
|
||||
src-tauri\target\
|
||||
key: windows-x86_64-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
key: windows-${{ matrix.arch }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: |
|
||||
windows-x86_64-cargo-
|
||||
windows-${{ matrix.arch }}-cargo-
|
||||
|
||||
- name: Install frontend dependencies
|
||||
working-directory: src-vite
|
||||
@@ -250,21 +266,21 @@ jobs:
|
||||
- name: Setup MSVC build environment
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x64
|
||||
arch: ${{ matrix.msvc_arch }}
|
||||
|
||||
- name: Clear cached Windows bundle artifacts
|
||||
shell: pwsh
|
||||
run: |
|
||||
$bundleDir = "src-tauri/target/x86_64-pc-windows-msvc/release/bundle"
|
||||
$bundleDir = "src-tauri/target/${{ matrix.target }}/release/bundle"
|
||||
if (Test-Path $bundleDir) {
|
||||
Remove-Item -Recurse -Force $bundleDir
|
||||
}
|
||||
|
||||
- name: Download FFmpeg Sidecars (Windows)
|
||||
shell: pwsh
|
||||
run: .\scripts\download_ffmpeg_sidecar.ps1
|
||||
run: .\scripts\download_ffmpeg_sidecar.ps1 -Arch ${{ matrix.arch }}
|
||||
|
||||
- name: Build and Sign (Windows x64)
|
||||
- name: Build and Sign (Windows ${{ matrix.arch }})
|
||||
uses: tauri-apps/tauri-action@v0.5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -273,13 +289,13 @@ jobs:
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
||||
with:
|
||||
projectPath: .
|
||||
args: --verbose --target x86_64-pc-windows-msvc --bundles msi --config '{"bundle":{"createUpdaterArtifacts":false}}'
|
||||
args: --verbose --target ${{ matrix.target }} --bundles msi --config '{"bundle":{"createUpdaterArtifacts":false}}'
|
||||
|
||||
- name: Rename Windows package for PR build
|
||||
shell: pwsh
|
||||
run: |
|
||||
$suffix = "pr-${{ github.event.pull_request.number || github.run_number }}"
|
||||
$msi = Get-ChildItem -Path "src-tauri/target/x86_64-pc-windows-msvc/release/bundle/msi" -Filter "*.msi" -File | Select-Object -First 1
|
||||
$msi = Get-ChildItem -Path "src-tauri/target/${{ matrix.target }}/release/bundle/msi" -Filter "*.msi" -File | Select-Object -First 1
|
||||
if (-not $msi) {
|
||||
throw "Could not find generated MSI file."
|
||||
}
|
||||
@@ -296,10 +312,10 @@ jobs:
|
||||
- name: Upload Windows artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: lap-pr-windows-x64-${{ github.event.pull_request.number || github.run_number }}
|
||||
name: lap-pr-windows-${{ matrix.arch }}-${{ github.event.pull_request.number || github.run_number }}
|
||||
path: |
|
||||
src-tauri/target/x86_64-pc-windows-msvc/release/bundle/msi/*.msi
|
||||
src-tauri/target/x86_64-pc-windows-msvc/release/bundle/msi/*.msi.sig
|
||||
src-tauri/target/${{ matrix.target }}/release/bundle/msi/*.msi
|
||||
src-tauri/target/${{ matrix.target }}/release/bundle/msi/*.msi.sig
|
||||
if-no-files-found: error
|
||||
|
||||
build-linux:
|
||||
@@ -373,6 +389,10 @@ jobs:
|
||||
shell: bash
|
||||
run: bash scripts/download_models.sh
|
||||
|
||||
- name: Clear cached Linux bundle artifacts
|
||||
shell: bash
|
||||
run: rm -rf src-tauri/target/x86_64-unknown-linux-gnu/release/bundle
|
||||
|
||||
- name: Build and Sign
|
||||
uses: tauri-apps/tauri-action@v0.5
|
||||
env:
|
||||
|
||||
@@ -7,13 +7,55 @@ on:
|
||||
description: "Existing release tag to publish Windows assets to"
|
||||
required: true
|
||||
type: string
|
||||
build_target:
|
||||
description: "Architecture to build"
|
||||
required: false
|
||||
default: "all"
|
||||
type: choice
|
||||
options:
|
||||
- all
|
||||
- x64
|
||||
- arm64
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- id: set-matrix
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
ALL='[
|
||||
{"arch":"x64","runner":"windows-latest","target":"x86_64-pc-windows-msvc","msvc_arch":"x64","platform_key":"windows-x86_64","artifact_name":"windows-x86_64","msi_glob":"*_x64_*.msi"},
|
||||
{"arch":"arm64","runner":"windows-11-arm","target":"aarch64-pc-windows-msvc","msvc_arch":"arm64","platform_key":"windows-aarch64","artifact_name":"windows-aarch64","msi_glob":"*_arm64_*.msi"}
|
||||
]'
|
||||
|
||||
INPUT="${{ github.event.inputs.build_target }}"
|
||||
if [ -z "$INPUT" ] || [ "$INPUT" = "all" ]; then
|
||||
SEL="$ALL"
|
||||
else
|
||||
SEL=$(echo "$ALL" | jq -c --arg a "$INPUT" '[.[] | select(.arch == $a)]')
|
||||
if [ "$SEL" = "[]" ]; then
|
||||
echo "Unknown build_target: $INPUT"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
MATRIX=$(echo "$SEL" | jq -c '{include: .}')
|
||||
echo "Generated matrix: $MATRIX"
|
||||
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
needs: setup
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -40,14 +82,14 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: windows-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
key: windows-${{ matrix.arch }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
windows-pnpm-store-
|
||||
windows-${{ matrix.arch }}-pnpm-store-
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: x86_64-pc-windows-msvc
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- name: Cache Rust dependencies
|
||||
uses: actions/cache@v4
|
||||
@@ -58,9 +100,9 @@ jobs:
|
||||
~\.cargo\registry\cache\
|
||||
~\.cargo\git\db\
|
||||
src-tauri\target\
|
||||
key: windows-x86_64-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
key: windows-${{ matrix.arch }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: |
|
||||
windows-x86_64-cargo-
|
||||
windows-${{ matrix.arch }}-cargo-
|
||||
|
||||
- name: Install frontend dependencies
|
||||
working-directory: src-vite
|
||||
@@ -81,22 +123,21 @@ jobs:
|
||||
- name: Setup MSVC build environment
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x64
|
||||
arch: ${{ matrix.msvc_arch }}
|
||||
|
||||
- name: Clear cached Windows bundle artifacts
|
||||
shell: pwsh
|
||||
run: |
|
||||
$bundleDir = "src-tauri/target/x86_64-pc-windows-msvc/release/bundle"
|
||||
$bundleDir = "src-tauri/target/${{ matrix.target }}/release/bundle"
|
||||
if (Test-Path $bundleDir) {
|
||||
Remove-Item -Recurse -Force $bundleDir
|
||||
}
|
||||
|
||||
|
||||
- name: Download FFmpeg Sidecars (Windows)
|
||||
shell: pwsh
|
||||
run: .\scripts\download_ffmpeg_sidecar.ps1
|
||||
run: .\scripts\download_ffmpeg_sidecar.ps1 -Arch ${{ matrix.arch }}
|
||||
|
||||
- name: Build and Sign (Windows x64)
|
||||
- name: Build and Sign (Windows ${{ matrix.arch }})
|
||||
uses: tauri-apps/tauri-action@v0.5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -105,15 +146,15 @@ jobs:
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
||||
with:
|
||||
projectPath: .
|
||||
args: --verbose --target x86_64-pc-windows-msvc --bundles msi
|
||||
args: --verbose --target ${{ matrix.target }} --bundles msi
|
||||
|
||||
- name: Upload Build Artifact (Windows)
|
||||
- name: Upload Build Artifact (Windows ${{ matrix.arch }})
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows-x86_64
|
||||
name: ${{ matrix.artifact_name }}
|
||||
path: |
|
||||
src-tauri/target/x86_64-pc-windows-msvc/release/bundle/msi/*.msi
|
||||
src-tauri/target/x86_64-pc-windows-msvc/release/bundle/msi/*.msi.sig
|
||||
src-tauri/target/${{ matrix.target }}/release/bundle/msi/*.msi
|
||||
src-tauri/target/${{ matrix.target }}/release/bundle/msi/*.msi.sig
|
||||
if-no-files-found: error
|
||||
|
||||
publish-windows:
|
||||
@@ -124,8 +165,9 @@ jobs:
|
||||
- name: Download Windows artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: windows-x86_64
|
||||
pattern: windows-*
|
||||
path: release-files
|
||||
merge-multiple: true
|
||||
|
||||
- name: Show release files
|
||||
run: ls -la release-files
|
||||
@@ -156,7 +198,7 @@ jobs:
|
||||
echo "Timed out waiting for latest.json on release $TAG."
|
||||
exit 1
|
||||
|
||||
- name: Update latest.json with Windows updater entry
|
||||
- name: Update latest.json with Windows updater entries
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
@@ -164,20 +206,8 @@ jobs:
|
||||
set -euo pipefail
|
||||
TAG="${{ github.event.inputs.release_tag }}"
|
||||
VERSION="${TAG#v}"
|
||||
|
||||
MSI_FILE="$(find release-files -maxdepth 1 -name '*.msi' | head -n 1)"
|
||||
MSI_SIG_FILE="$(find release-files -maxdepth 1 -name '*.msi.sig' | head -n 1)"
|
||||
if [ -z "${MSI_FILE}" ] || [ ! -f "${MSI_FILE}" ]; then
|
||||
echo "No MSI installer (*.msi) found."
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${MSI_SIG_FILE}" ] || [ ! -f "${MSI_SIG_FILE}" ]; then
|
||||
echo "Missing MSI updater signature file (*.msi.sig)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MSI_NAME="$(basename "${MSI_FILE}")"
|
||||
WINDOWS_SIG="$(cat "${MSI_SIG_FILE}")"
|
||||
REPO="${{ github.repository }}"
|
||||
PUB_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
|
||||
rm -f release-files/latest.json
|
||||
gh release download "$TAG" -R "$GH_REPO" -p "latest.json" -D release-files >/dev/null 2>&1
|
||||
@@ -186,19 +216,52 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmp="$(mktemp)"
|
||||
jq \
|
||||
--arg version "${VERSION}" \
|
||||
--arg pub_date "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
--arg sig "${WINDOWS_SIG}" \
|
||||
--arg url "https://github.com/${{ github.repository }}/releases/download/${TAG}/${MSI_NAME}" \
|
||||
'
|
||||
.version = $version
|
||||
| .pub_date = $pub_date
|
||||
| .platforms = (.platforms // {})
|
||||
| .platforms["windows-x86_64"] = {"signature": $sig, "url": $url}
|
||||
' release-files/latest.json > "$tmp"
|
||||
mv "$tmp" release-files/latest.json
|
||||
# merge_entry <platform_key> <msi_glob>
|
||||
# Tauri's MSI filename embeds the architecture: "Lap_<version>_x64_en-US.msi"
|
||||
# or "Lap_<version>_arm64_en-US.msi", so we can separate architectures by glob.
|
||||
merge_entry() {
|
||||
local key="$1"
|
||||
local glob="$2"
|
||||
|
||||
local msi
|
||||
msi="$(find release-files -maxdepth 1 -type f -name "$glob" ! -name '*.sig' | head -n 1)"
|
||||
if [ -z "${msi}" ]; then
|
||||
echo "No MSI found matching '$glob' for $key — skipping."
|
||||
return 0
|
||||
fi
|
||||
|
||||
local sig_file="${msi}.sig"
|
||||
if [ ! -f "$sig_file" ]; then
|
||||
echo "Missing updater signature file for $msi ($key)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local name sig_content tmp
|
||||
name="$(basename "$msi")"
|
||||
sig_content="$(cat "$sig_file")"
|
||||
tmp="$(mktemp)"
|
||||
|
||||
jq \
|
||||
--arg version "$VERSION" \
|
||||
--arg pub_date "$PUB_DATE" \
|
||||
--arg key "$key" \
|
||||
--arg sig "$sig_content" \
|
||||
--arg url "https://github.com/${REPO}/releases/download/${TAG}/${name}" \
|
||||
'
|
||||
.version = $version
|
||||
| .pub_date = $pub_date
|
||||
| .platforms = (.platforms // {})
|
||||
| .platforms[$key] = {"signature": $sig, "url": $url}
|
||||
' release-files/latest.json > "$tmp"
|
||||
mv "$tmp" release-files/latest.json
|
||||
echo "Recorded $key -> $name"
|
||||
}
|
||||
|
||||
merge_entry "windows-x86_64" "*_x64_*.msi"
|
||||
merge_entry "windows-aarch64" "*_arm64_*.msi"
|
||||
|
||||
echo "Final latest.json:"
|
||||
cat release-files/latest.json
|
||||
|
||||
- name: Upload Windows assets to GitHub Release
|
||||
env:
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[ValidateSet("x64", "x86_64", "arm64", "aarch64")]
|
||||
[string]$Arch
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
@@ -7,25 +13,55 @@ if (-not (Test-Path $TargetDir)) {
|
||||
New-Item -ItemType Directory -Path $TargetDir -Force | Out-Null
|
||||
}
|
||||
|
||||
if (-not $Arch) {
|
||||
$procArch = $env:PROCESSOR_ARCHITECTURE
|
||||
if ($procArch -eq "ARM64") {
|
||||
$Arch = "arm64"
|
||||
}
|
||||
else {
|
||||
$Arch = "x64"
|
||||
}
|
||||
Write-Host "No -Arch specified; auto-detected $Arch (PROCESSOR_ARCHITECTURE=$procArch)."
|
||||
}
|
||||
|
||||
switch ($Arch) {
|
||||
{ $_ -in "x64", "x86_64" } {
|
||||
$TripleSuffix = "x86_64-pc-windows-msvc"
|
||||
}
|
||||
{ $_ -in "arm64", "aarch64" } {
|
||||
$TripleSuffix = "aarch64-pc-windows-msvc"
|
||||
}
|
||||
default {
|
||||
throw "Unsupported architecture: $Arch"
|
||||
}
|
||||
}
|
||||
|
||||
$ReleaseBase = "https://github.com/julyx10/lap-binaries/releases/download/ffmpeg-8.1"
|
||||
|
||||
$Downloads = @(
|
||||
"ffmpeg-x86_64-pc-windows-msvc.exe",
|
||||
"ffprobe-x86_64-pc-windows-msvc.exe"
|
||||
"ffmpeg-$TripleSuffix.exe",
|
||||
"ffprobe-$TripleSuffix.exe"
|
||||
)
|
||||
|
||||
Write-Host "Downloading FFmpeg sidecar files into $TargetDir..."
|
||||
Write-Host "Downloading FFmpeg sidecar files ($Arch) into $TargetDir..."
|
||||
foreach ($Filename in $Downloads) {
|
||||
$Url = "$ReleaseBase/$Filename"
|
||||
$Dest = Join-Path $TargetDir $Filename
|
||||
|
||||
if (Test-Path $Dest) {
|
||||
Write-Host "✓ $Filename already exists, skipping."
|
||||
Write-Host "# $Filename already exists, skipping."
|
||||
continue
|
||||
}
|
||||
|
||||
Write-Host "⬇ Downloading $Filename..."
|
||||
Invoke-WebRequest -Uri $Url -OutFile $Dest -UseBasicParsing
|
||||
Write-Host "✓ $Filename downloaded."
|
||||
Write-Host "# Downloading $Filename..."
|
||||
try {
|
||||
Invoke-WebRequest -Uri $Url -OutFile $Dest -UseBasicParsing
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to download $Url. If this is an arm64 build and the binary has not been published yet, upload ffmpeg-aarch64-pc-windows-msvc.exe and ffprobe-aarch64-pc-windows-msvc.exe to the julyx10/lap-binaries release tag 'ffmpeg-8.1', or temporarily use the x64 binaries via Windows 11 ARM64 emulation."
|
||||
throw
|
||||
}
|
||||
Write-Host "# $Filename downloaded."
|
||||
}
|
||||
|
||||
Write-Host "All FFmpeg sidecar files downloaded into $TargetDir."
|
||||
Write-Host "All FFmpeg sidecar files downloaded into $TargetDir."
|
||||
|
||||
Generated
+39
-195
@@ -11,6 +11,7 @@ dependencies = [
|
||||
"blake3",
|
||||
"cc",
|
||||
"chrono",
|
||||
"csv",
|
||||
"dirs 5.0.1",
|
||||
"fast_image_resize",
|
||||
"http",
|
||||
@@ -26,7 +27,7 @@ dependencies = [
|
||||
"ort",
|
||||
"pinyin",
|
||||
"rand 0.8.5",
|
||||
"reverse_geocoder",
|
||||
"rstar",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -261,12 +262,6 @@ dependencies = [
|
||||
"arrayvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "az"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
@@ -1082,12 +1077,6 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "divrem"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69dde51e8fef5e12c1d65e0929b03d66e4c0c18282bc30ed2ca050ad6f44dd82"
|
||||
|
||||
[[package]]
|
||||
name = "dlopen2"
|
||||
version = "0.8.2"
|
||||
@@ -1111,12 +1100,6 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "780955b8b195a21ab8e4ac6b60dd1dbdcec1dc6c51c0617964b08c81785e12c9"
|
||||
|
||||
[[package]]
|
||||
name = "document-features"
|
||||
version = "0.2.12"
|
||||
@@ -1183,12 +1166,6 @@ version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "elapsed"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f4e5af126dafd0741c2ad62d47f68b28602550102e5f0dd45c8a97fc8b49c29"
|
||||
|
||||
[[package]]
|
||||
name = "embed-resource"
|
||||
version = "3.0.8"
|
||||
@@ -1378,19 +1355,6 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||
|
||||
[[package]]
|
||||
name = "fixed"
|
||||
version = "1.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9af2cbf772fa6d1c11358f92ef554cb6b386201210bcf0e91fb7fba8a907fb40"
|
||||
dependencies = [
|
||||
"az",
|
||||
"bytemuck",
|
||||
"half",
|
||||
"num-traits",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.9"
|
||||
@@ -1676,21 +1640,6 @@ dependencies = [
|
||||
"x11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generator"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52f04ae4152da20c76fe800fa48659201d5cf627c5149ca0b707b69d7eef6cf9"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"log",
|
||||
"rustversion",
|
||||
"windows-link 0.2.1",
|
||||
"windows-result 0.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
@@ -1946,6 +1895,15 @@ dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hash32"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
@@ -1985,6 +1943,16 @@ dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
|
||||
dependencies = [
|
||||
"hash32",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
@@ -2375,12 +2343,6 @@ dependencies = [
|
||||
"cfb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "init_with"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0175f63815ce00183bf755155ad0cb48c65226c5d17a724e369c25418d2b7699"
|
||||
|
||||
[[package]]
|
||||
name = "interpolate_name"
|
||||
version = "0.2.4"
|
||||
@@ -2445,15 +2407,6 @@ dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.14.0"
|
||||
@@ -2780,29 +2733,6 @@ dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kiddo"
|
||||
version = "4.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60c5fcd3044b774e2c80a502b2387b75d1baa95e99b2bceeb5db00f2e2d27fe9"
|
||||
dependencies = [
|
||||
"az",
|
||||
"divrem",
|
||||
"doc-comment",
|
||||
"elapsed",
|
||||
"fixed",
|
||||
"generator",
|
||||
"init_with",
|
||||
"itertools 0.13.0",
|
||||
"log",
|
||||
"num-traits",
|
||||
"ordered-float",
|
||||
"sorted-vec",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"ubyte",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kuchikiki"
|
||||
version = "0.8.8-speedreader"
|
||||
@@ -2893,6 +2823,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.15"
|
||||
@@ -3298,15 +3234,6 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.50.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
@@ -3370,6 +3297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3714,15 +3642,6 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "4.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ort"
|
||||
version = "2.0.0-rc.10"
|
||||
@@ -4698,18 +4617,6 @@ dependencies = [
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reverse_geocoder"
|
||||
version = "4.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c987d5006fe57c099370a219602d52da978376fa7bf3324e036ad647beafda2"
|
||||
dependencies = [
|
||||
"csv",
|
||||
"kiddo",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rfd"
|
||||
version = "0.16.0"
|
||||
@@ -4754,6 +4661,17 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rstar"
|
||||
version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "421400d13ccfd26dfa5858199c30a5d76f9c54e0dba7575273025b43c5175dbb"
|
||||
dependencies = [
|
||||
"heapless",
|
||||
"num-traits",
|
||||
"smallvec 1.15.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
version = "0.32.1"
|
||||
@@ -5216,15 +5134,6 @@ dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shared_child"
|
||||
version = "1.1.1"
|
||||
@@ -5361,12 +5270,6 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sorted-vec"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19f58d7b0190c7f12df7e8be6b79767a0836059159811b869d5ab55721fe14d0"
|
||||
|
||||
[[package]]
|
||||
name = "soup3"
|
||||
version = "0.5.0"
|
||||
@@ -6097,15 +6000,6 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiff"
|
||||
version = "0.11.3"
|
||||
@@ -6410,21 +6304,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.36"
|
||||
@@ -6432,32 +6314,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319"
|
||||
dependencies = [
|
||||
"nu-ansi-term",
|
||||
"sharded-slab",
|
||||
"smallvec 1.15.1",
|
||||
"thread_local",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6516,12 +6372,6 @@ version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
||||
|
||||
[[package]]
|
||||
name = "ubyte"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f720def6ce1ee2fc44d40ac9ed6d3a59c361c80a75a7aa8e75bb9baed31cf2ea"
|
||||
|
||||
[[package]]
|
||||
name = "unic-char-property"
|
||||
version = "0.9.0"
|
||||
@@ -6698,12 +6548,6 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
|
||||
@@ -41,7 +41,8 @@ serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
rusqlite = { version = "0.32.1", features = ["bundled", "collation"] }
|
||||
chrono = "0.4"
|
||||
reverse_geocoder = "4.1.1"
|
||||
rstar = "0.12"
|
||||
csv = "1"
|
||||
dirs = "5.0.1"
|
||||
walkdir = "2.5.0"
|
||||
trash = "3.3.1"
|
||||
@@ -75,4 +76,4 @@ libc = "0.2"
|
||||
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
|
||||
default = ["custom-protocol"]
|
||||
custom-protocol = ["tauri/custom-protocol"]
|
||||
devtools = ["tauri/devtools"]
|
||||
devtools = ["tauri/devtools"]
|
||||
+144564
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@ use crate::t_sqlite::{AFile, Album};
|
||||
use chrono::{DateTime, Local, TimeZone, Utc};
|
||||
use once_cell::sync::Lazy;
|
||||
use pinyin::ToPinyin;
|
||||
use reverse_geocoder::ReverseGeocoder;
|
||||
use rstar::{AABB, PointDistance, RTree, RTreeObject};
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::io::Read;
|
||||
@@ -29,6 +29,86 @@ use walkdir::WalkDir; // https://docs.rs/walkdir/2.5.0/walkdir/
|
||||
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
|
||||
|
||||
// reverse geocoder
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct GeoRecord {
|
||||
pub lat: f64,
|
||||
pub lon: f64,
|
||||
pub name: String,
|
||||
pub admin1: String,
|
||||
pub admin2: String,
|
||||
pub cc: String,
|
||||
}
|
||||
|
||||
struct CityPoint {
|
||||
xyz: [f64; 3],
|
||||
idx: u32,
|
||||
}
|
||||
|
||||
impl RTreeObject for CityPoint {
|
||||
type Envelope = AABB<[f64; 3]>;
|
||||
fn envelope(&self) -> Self::Envelope {
|
||||
AABB::from_point(self.xyz)
|
||||
}
|
||||
}
|
||||
|
||||
impl PointDistance for CityPoint {
|
||||
fn distance_2(&self, point: &[f64; 3]) -> f64 {
|
||||
let dx = self.xyz[0] - point[0];
|
||||
let dy = self.xyz[1] - point[1];
|
||||
let dz = self.xyz[2] - point[2];
|
||||
dx * dx + dy * dy + dz * dz
|
||||
}
|
||||
}
|
||||
|
||||
fn lat_lon_to_xyz(lat: f64, lon: f64) -> [f64; 3] {
|
||||
let lat = lat.to_radians();
|
||||
let lon = lon.to_radians();
|
||||
[lat.cos() * lon.cos(), lat.cos() * lon.sin(), lat.sin()]
|
||||
}
|
||||
|
||||
pub struct ReverseGeocoder {
|
||||
records: Vec<GeoRecord>,
|
||||
tree: RTree<CityPoint>,
|
||||
}
|
||||
|
||||
pub struct SearchResult<'a> {
|
||||
pub record: &'a GeoRecord,
|
||||
}
|
||||
|
||||
impl ReverseGeocoder {
|
||||
pub fn new() -> ReverseGeocoder {
|
||||
let cities = include_str!("../data/cities.csv");
|
||||
let mut reader = csv::ReaderBuilder::new()
|
||||
.has_headers(true)
|
||||
.from_reader(cities.as_bytes());
|
||||
let mut records: Vec<GeoRecord> = Vec::with_capacity(150_000);
|
||||
let mut points: Vec<CityPoint> = Vec::with_capacity(150_000);
|
||||
for row in reader.deserialize() {
|
||||
let r: GeoRecord = row.expect("malformed cities.csv row");
|
||||
points.push(CityPoint {
|
||||
xyz: lat_lon_to_xyz(r.lat, r.lon),
|
||||
idx: records.len() as u32,
|
||||
});
|
||||
records.push(r);
|
||||
}
|
||||
ReverseGeocoder {
|
||||
records,
|
||||
tree: RTree::bulk_load(points),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn search(&self, loc: (f64, f64)) -> SearchResult<'_> {
|
||||
let query = lat_lon_to_xyz(loc.0, loc.1);
|
||||
let nearest = self
|
||||
.tree
|
||||
.nearest_neighbor(&query)
|
||||
.expect("cities tree is empty");
|
||||
SearchResult {
|
||||
record: &self.records[nearest.idx as usize],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub static GEOCODER: Lazy<ReverseGeocoder> = Lazy::new(|| {
|
||||
println!("Initializing ReverseGeocoder...");
|
||||
ReverseGeocoder::new()
|
||||
|
||||
@@ -98,10 +98,14 @@ fn ffmpeg_sidecar_name() -> &'static str {
|
||||
{
|
||||
"ffmpeg-aarch64-unknown-linux-gnu"
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
#[cfg(all(target_os = "windows", target_arch = "x86_64"))]
|
||||
{
|
||||
"ffmpeg-x86_64-pc-windows-msvc.exe"
|
||||
}
|
||||
#[cfg(all(target_os = "windows", target_arch = "aarch64"))]
|
||||
{
|
||||
"ffmpeg-aarch64-pc-windows-msvc.exe"
|
||||
}
|
||||
}
|
||||
|
||||
fn ffprobe_sidecar_name() -> &'static str {
|
||||
@@ -121,10 +125,14 @@ fn ffprobe_sidecar_name() -> &'static str {
|
||||
{
|
||||
"ffprobe-aarch64-unknown-linux-gnu"
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
#[cfg(all(target_os = "windows", target_arch = "x86_64"))]
|
||||
{
|
||||
"ffprobe-x86_64-pc-windows-msvc.exe"
|
||||
}
|
||||
#[cfg(all(target_os = "windows", target_arch = "aarch64"))]
|
||||
{
|
||||
"ffprobe-aarch64-pc-windows-msvc.exe"
|
||||
}
|
||||
}
|
||||
|
||||
fn find_sidecar(name: &str) -> Option<PathBuf> {
|
||||
|
||||
Reference in New Issue
Block a user