feat: initial release v0.0.1
11
.cargo/config.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
[target.aarch64-linux-android]
|
||||||
|
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]
|
||||||
|
|
||||||
|
[target.armv7-linux-androideabi]
|
||||||
|
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]
|
||||||
|
|
||||||
|
[target.x86_64-linux-android]
|
||||||
|
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]
|
||||||
|
|
||||||
|
[target.i686-linux-android]
|
||||||
|
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]
|
||||||
180
.github/workflows/release.yml
vendored
Normal file
|
|
@ -0,0 +1,180 @@
|
||||||
|
name: Release Build & Auto-Updater
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
tag:
|
||||||
|
description: 'Target Release Tag (e.g. v0.1.5)'
|
||||||
|
required: false
|
||||||
|
default: 'v0.1.5'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- platform: 'macos-latest'
|
||||||
|
target: 'aarch64-apple-darwin'
|
||||||
|
- platform: 'windows-latest'
|
||||||
|
target: 'x86_64-pc-windows-msvc'
|
||||||
|
- platform: 'ubuntu-22.04'
|
||||||
|
target: 'x86_64-unknown-linux-gnu'
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Linux build dependencies
|
||||||
|
if: matrix.platform == 'ubuntu-22.04'
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libssl-dev rpm
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: Setup Rust stable
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
targets: ${{ matrix.target }}
|
||||||
|
|
||||||
|
- name: Rust cache
|
||||||
|
uses: swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
workspaces: './src-tauri -> target'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm install
|
||||||
|
|
||||||
|
- name: Build Tauri and publish Release
|
||||||
|
uses: tauri-apps/tauri-action@v0
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY || 'dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5VUF0UnlMZjR6bE4vUUFIbnQ0MDdjQ01xSXBHUVVMZ0k2OURzMEhrbkZwNEFBQkFBQUFBQUFBQUFBQUlBQUFBQU1GZmxKUFZFcGJXSW1LUlRvVXN6SjJSV1FYMnhYQldjOFRtTE4rRkRSUGEvM0xDVFZPOVovL3Q1N3Rmdi9PUG9XOWxGdHM5bjFNc3BKZCtCWHdkWDVsNW9LaHhZNXpFbFNSYkNkeXFLQmRuNmNyeHA0Rlp4UVhSUENPUFJrUnVCandLd2ZBSy95V2M9Cg==' }}
|
||||||
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ''
|
||||||
|
with:
|
||||||
|
tagName: ${{ inputs.tag || github.ref_name }}
|
||||||
|
releaseName: 'Home Autli Server ${{ inputs.tag || github.ref_name }}'
|
||||||
|
releaseBody: 'Автоматический релиз для Android (.apk), Linux (.deb, .rpm, .AppImage), Windows (.exe) и macOS (.dmg).'
|
||||||
|
releaseDraft: false
|
||||||
|
prerelease: false
|
||||||
|
args: ${{ matrix.target && format('--target {0}', matrix.target) || '' }}
|
||||||
|
|
||||||
|
release-android:
|
||||||
|
needs: release
|
||||||
|
if: always() && (needs.release.result == 'success' || needs.release.result == 'skipped')
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Java JDK
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: '17'
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: Setup Rust stable
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
targets: aarch64-linux-android,armv7-linux-androideabi
|
||||||
|
|
||||||
|
- name: Setup Android NDK
|
||||||
|
run: |
|
||||||
|
echo "ANDROID_HOME=$ANDROID_SDK_ROOT" >> $GITHUB_ENV
|
||||||
|
if [ -d "$ANDROID_SDK_ROOT/ndk/26.1.10909125" ]; then
|
||||||
|
NDK_PATH="$ANDROID_SDK_ROOT/ndk/26.1.10909125"
|
||||||
|
else
|
||||||
|
NDK_LATEST=$(ls -d $ANDROID_SDK_ROOT/ndk/* 2>/dev/null | tail -n 1 || true)
|
||||||
|
if [ -n "$NDK_LATEST" ]; then
|
||||||
|
NDK_PATH="$NDK_LATEST"
|
||||||
|
else
|
||||||
|
echo "y" | $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager "ndk;26.1.10909125"
|
||||||
|
NDK_PATH="$ANDROID_SDK_ROOT/ndk/26.1.10909125"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "NDK_HOME=$NDK_PATH" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
TOOLCHAIN="$NDK_PATH/toolchains/llvm/prebuilt/linux-x86_64"
|
||||||
|
echo "TOOLCHAIN=$TOOLCHAIN" >> $GITHUB_ENV
|
||||||
|
echo "$TOOLCHAIN/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
|
# Create symlinks for legacy GNU binutils expected by OpenSSL makefile
|
||||||
|
for prefix in aarch64-linux-android arm-linux-androideabi armv7a-linux-androideabi; do
|
||||||
|
sudo ln -sf "$TOOLCHAIN/bin/llvm-ar" "/usr/local/bin/${prefix}-ar"
|
||||||
|
sudo ln -sf "$TOOLCHAIN/bin/llvm-ranlib" "/usr/local/bin/${prefix}-ranlib"
|
||||||
|
sudo ln -sf "$TOOLCHAIN/bin/llvm-nm" "/usr/local/bin/${prefix}-nm"
|
||||||
|
sudo ln -sf "$TOOLCHAIN/bin/llvm-as" "/usr/local/bin/${prefix}-as"
|
||||||
|
sudo ln -sf "$TOOLCHAIN/bin/llvm-strip" "/usr/local/bin/${prefix}-strip"
|
||||||
|
|
||||||
|
sudo ln -sf "$TOOLCHAIN/bin/llvm-ar" "$TOOLCHAIN/bin/${prefix}-ar"
|
||||||
|
sudo ln -sf "$TOOLCHAIN/bin/llvm-ranlib" "$TOOLCHAIN/bin/${prefix}-ranlib"
|
||||||
|
sudo ln -sf "$TOOLCHAIN/bin/llvm-nm" "$TOOLCHAIN/bin/${prefix}-nm"
|
||||||
|
sudo ln -sf "$TOOLCHAIN/bin/llvm-as" "$TOOLCHAIN/bin/${prefix}-as"
|
||||||
|
sudo ln -sf "$TOOLCHAIN/bin/llvm-strip" "$TOOLCHAIN/bin/${prefix}-strip"
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm install
|
||||||
|
|
||||||
|
- name: Build Android APK
|
||||||
|
run: npm run tauri -- android build --apk --target aarch64 armv7
|
||||||
|
env:
|
||||||
|
NDK_HOME: ${{ env.NDK_HOME }}
|
||||||
|
OPENSSL_STATIC: "1"
|
||||||
|
AR_aarch64_linux_android: llvm-ar
|
||||||
|
RANLIB_aarch64_linux_android: llvm-ranlib
|
||||||
|
AR_armv7_linux_androideabi: llvm-ar
|
||||||
|
RANLIB_armv7_linux_androideabi: llvm-ranlib
|
||||||
|
|
||||||
|
- name: Upload APK to GitHub Release
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
RELEASE_TAG="${{ inputs.tag || github.ref_name }}"
|
||||||
|
echo "Target Release Tag is: $RELEASE_TAG"
|
||||||
|
|
||||||
|
mkdir -p dist-apk
|
||||||
|
for apk in $(find src-tauri/gen/android/app/build/outputs/apk -type f -name "*.apk"); do
|
||||||
|
filename=$(basename "$apk")
|
||||||
|
echo "Found APK: $apk ($filename)"
|
||||||
|
cp "$apk" "dist-apk/Home.Autli.Server_${RELEASE_TAG}_${filename}"
|
||||||
|
if [[ "$filename" == *"universal"* ]] || [[ "$filename" == *"release"* ]]; then
|
||||||
|
cp "$apk" "dist-apk/Home.Autli.Server_${RELEASE_TAG}.apk"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -f "dist-apk/Home.Autli.Server_${RELEASE_TAG}.apk" ]; then
|
||||||
|
first_apk=$(find dist-apk -type f -name "*.apk" | head -n 1)
|
||||||
|
if [ -n "$first_apk" ]; then
|
||||||
|
cp "$first_apk" "dist-apk/Home.Autli.Server_${RELEASE_TAG}.apk"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Uploading APK assets to GitHub release $RELEASE_TAG..."
|
||||||
|
if ! gh release view "$RELEASE_TAG" >/dev/null 2>&1; then
|
||||||
|
gh release create "$RELEASE_TAG" --title "Home Autli Server $RELEASE_TAG" --notes "Release $RELEASE_TAG"
|
||||||
|
fi
|
||||||
|
gh release upload "$RELEASE_TAG" dist-apk/*.apk --clobber
|
||||||
30
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
|
# Environment variables (NEVER commit any .env file to GitHub!)
|
||||||
|
.env*
|
||||||
|
|
||||||
|
# Tauri update private signing key (KEEP SECRET!)
|
||||||
|
src-tauri/*.key
|
||||||
3
.vscode/extensions.json
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"]
|
||||||
|
}
|
||||||
31
PKGBUILD
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Maintainer: autli5 <https://github.com/autli5>
|
||||||
|
pkgname=home-autli-server-bin
|
||||||
|
pkgver=0.1.5
|
||||||
|
pkgrel=1
|
||||||
|
pkgdesc="Home Autli Server (HAS) - Кинотеатр (Full HD + Русская озвучка) и Облачное хранилище"
|
||||||
|
arch=('x86_64')
|
||||||
|
url="https://github.com/autli5/has"
|
||||||
|
license=('custom')
|
||||||
|
depends=('webkit2gtk-4.1' 'libappindicator-gtk3' 'librsvg' 'openssl' 'hicolor-icon-theme')
|
||||||
|
options=(!strip)
|
||||||
|
|
||||||
|
source=(
|
||||||
|
"https://github.com/autli5/has/releases/download/v${pkgver}/home-autli-server_${pkgver}_amd64.deb"
|
||||||
|
"https://raw.githubusercontent.com/autli5/has/main/public/logo.png"
|
||||||
|
)
|
||||||
|
sha256sums=(
|
||||||
|
'SKIP'
|
||||||
|
'SKIP'
|
||||||
|
)
|
||||||
|
|
||||||
|
package() {
|
||||||
|
# Распаковываем DEB пакет
|
||||||
|
tar -xf data.tar.* -C "${pkgdir}/"
|
||||||
|
|
||||||
|
# Устанавливаем логотип
|
||||||
|
install -Dm644 "${srcdir}/logo.png" "${pkgdir}/usr/share/icons/hicolor/512x512/apps/has.png"
|
||||||
|
|
||||||
|
# Создаем симлинк для быстрого запуска через 'has' в терминале
|
||||||
|
mkdir -p "${pkgdir}/usr/bin"
|
||||||
|
ln -sf "/usr/bin/home-autli-server" "${pkgdir}/usr/bin/has"
|
||||||
|
}
|
||||||
90
README.md
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
# Home Autli Server (HAS) 🚀
|
||||||
|
|
||||||
|
> **Личный облачный сервер, Кинотеатр Full HD с полной русской озвучкой (дубляж) и защищенное хранилище данных.**
|
||||||
|
|
||||||
|
[](https://github.com/autli5/has/actions/workflows/release.yml)
|
||||||
|
[](https://github.com/autli5/has/releases/latest)
|
||||||
|
[](https://github.com/autli5/has/releases/latest)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚡ Быстрая установка на Linux через Терминал
|
||||||
|
|
||||||
|
Поддерживаются любые дистрибутивы: **Ubuntu, Debian, Fedora, Arch Linux, CachyOS, Manjaro, Linux Mint, Pop!_OS** и другие.
|
||||||
|
|
||||||
|
Выполните одну команду в терминале:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/autli5/has/main/install.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
*или через `wget`:*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget -qO- https://raw.githubusercontent.com/autli5/has/main/install.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
Установщик сам определит ваш дистрибутив (Debian, Ubuntu, Fedora, Arch, CachyOS), скачает подходящий пакет (`.deb`, `.rpm` или `.AppImage`), установит необходимые зависимости и создаст ярлык в меню приложений.
|
||||||
|
|
||||||
|
Запуск из терминала:
|
||||||
|
```bash
|
||||||
|
has
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 Ручная установка по дистрибутивам
|
||||||
|
|
||||||
|
### 🐧 Ubuntu / Debian / Linux Mint / Pop!_OS (`.deb`)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Скачивание последнего пакета .deb
|
||||||
|
curl -s https://api.github.com/repos/autli5/has/releases/latest | grep "browser_download_url.*amd64.deb" | cut -d : -f 2,3 | tr -d \" | wget -qi -
|
||||||
|
|
||||||
|
# 2. Установка через dpkg
|
||||||
|
sudo dpkg -i home-autli-server_*_amd64.deb || sudo apt-get install -f -y
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🎩 Fedora / RHEL / CentOS (`.rpm`)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Скачивание пакета .rpm
|
||||||
|
curl -s https://api.github.com/repos/autli5/has/releases/latest | grep "browser_download_url.*x86_64.rpm" | cut -d : -f 2,3 | tr -d \" | wget -qi -
|
||||||
|
|
||||||
|
# 2. Установка через dnf
|
||||||
|
sudo dnf install -y ./home-autli-server-*.rpm
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🏹 Arch Linux / CachyOS / Manjaro / EndeavourOS
|
||||||
|
|
||||||
|
#### Вариант A: Через `install.sh` (Рекомендуется)
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/autli5/has/main/install.sh | bash -s -- --arch
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Вариант B: Через `PKGBUILD`
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/autli5/has.git
|
||||||
|
cd has
|
||||||
|
makepkg -si
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💻 Другие операционные системы
|
||||||
|
|
||||||
|
- **🍏 macOS (Apple Silicon & Intel):** Скачайте `.dmg` из [последнего релиза](https://github.com/autli5/has/releases/latest).
|
||||||
|
- **🪟 Windows 10/11 (64-bit):** Скачайте `.exe` установщик из [последнего релиза](https://github.com/autli5/has/releases/latest).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ Основные возможности приложения
|
||||||
|
|
||||||
|
- 🎬 **Кинотеатр нового поколения:**
|
||||||
|
- Огромный каталог фильмов, сериалов и аниме без региональных блокировок.
|
||||||
|
- **100% Русская озвучка / Дубляж по умолчанию:** Smotrim, Embess, Alloha (Red Head Sound, Flarrow Films, СНГ-дубляж).
|
||||||
|
- Студийные озвучки для аниме: **Studio Band, AniLibria, AniDUB, SHIZA Project**.
|
||||||
|
- Полноэкранный режим с поддержкой звука и выбором серий прямо в плеере.
|
||||||
|
- 📁 **Облачное хранилище файлов:** Загрузка, папки, превью и мгновенная синхронизация.
|
||||||
|
- 👤 **Профиль пользователя:** Настройка темы, персонализация и управление аккаунтом.
|
||||||
|
- 🔄 **Авто-обновления:** Встроенный механизм проверки и загрузки новых версий (Tauri Updater).
|
||||||
16
index.html
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/png" href="/logo.png" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<title>has</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
241
install.sh
Executable file
|
|
@ -0,0 +1,241 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# ==============================================================================
|
||||||
|
# Home Autli Server (HAS) - Универсальный установщик для Linux через терминал
|
||||||
|
# Поддерживает: Ubuntu, Debian, Fedora, Arch Linux, CachyOS, Manjaro и др.
|
||||||
|
#
|
||||||
|
# Быстрый запуск одной командой в терминале:
|
||||||
|
# curl -fsSL https://raw.githubusercontent.com/autli5/has/main/install.sh | bash
|
||||||
|
# или
|
||||||
|
# wget -qO- https://raw.githubusercontent.com/autli5/has/main/install.sh | bash
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
REPO="autli5/has"
|
||||||
|
APP_NAME="Home Autli Server"
|
||||||
|
BIN_NAME="has"
|
||||||
|
|
||||||
|
# Цвета для вывода в терминале
|
||||||
|
BOLD="\033[1m"
|
||||||
|
GREEN="\033[0;32m"
|
||||||
|
BLUE="\033[0;34m"
|
||||||
|
CYAN="\033[0;36m"
|
||||||
|
YELLOW="\033[1;33m"
|
||||||
|
RED="\033[0;31m"
|
||||||
|
RESET="\033[0m"
|
||||||
|
|
||||||
|
echo -e "${CYAN}${BOLD}"
|
||||||
|
echo "=========================================================="
|
||||||
|
echo " 🚀 Установка Home Autli Server (HAS) для Linux "
|
||||||
|
echo " Кинотеатр (Full HD + Русская озвучка) и Облако "
|
||||||
|
echo " Поддержка: Ubuntu, Debian, Fedora, Arch, CachyOS "
|
||||||
|
echo "=========================================================="
|
||||||
|
echo -e "${RESET}"
|
||||||
|
|
||||||
|
# 1. Проверка архитектуры системы
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
if [ "$ARCH" != "x86_64" ] && [ "$ARCH" != "aarch64" ]; then
|
||||||
|
echo -e "${RED}Ошибка: архитектура $ARCH не поддерживается.${RESET}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Определение дистрибутива Linux
|
||||||
|
PKG_TYPE=""
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--deb) PKG_TYPE="deb" ;;
|
||||||
|
--rpm) PKG_TYPE="rpm" ;;
|
||||||
|
--arch|--cachyos) PKG_TYPE="arch" ;;
|
||||||
|
--appimage) PKG_TYPE="appimage" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$PKG_TYPE" ]; then
|
||||||
|
if [ -f /etc/os-release ]; then
|
||||||
|
. /etc/os-release
|
||||||
|
DISTRO_ID="${ID:-linux}"
|
||||||
|
DISTRO_LIKE="${ID_LIKE:-}"
|
||||||
|
|
||||||
|
case "$DISTRO_ID $DISTRO_LIKE" in
|
||||||
|
*ubuntu*|*debian*|*linuxmint*|*pop*|*elementary*|*zorin*|*kali*)
|
||||||
|
PKG_TYPE="deb"
|
||||||
|
echo -e "${BLUE}ℹ️ Обнаружен дистрибутив Debian / Ubuntu (${DISTRO_ID}). Формат: .deb${RESET}"
|
||||||
|
;;
|
||||||
|
*fedora*|*rhel*|*centos*|*rocky*|*almalinux*)
|
||||||
|
PKG_TYPE="rpm"
|
||||||
|
echo -e "${BLUE}ℹ️ Обнаружен дистрибутив Fedora / Red Hat (${DISTRO_ID}). Формат: .rpm${RESET}"
|
||||||
|
;;
|
||||||
|
*arch*|*cachyos*|*cachy*|*manjaro*|*endeavouros*|*artix*)
|
||||||
|
PKG_TYPE="arch"
|
||||||
|
echo -e "${BLUE}ℹ️ Обнаружен дистрибутив Arch Linux / CachyOS (${DISTRO_ID}).${RESET}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
PKG_TYPE="appimage"
|
||||||
|
echo -e "${BLUE}ℹ️ Обнаружен дистрибутив Linux (${DISTRO_ID}). Формат: .AppImage${RESET}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
PKG_TYPE="appimage"
|
||||||
|
echo -e "${YELLOW}⚠️ Не удалось определить дистрибутив. Будет использован универсальный AppImage.${RESET}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3. Получение последней версии из GitHub Releases
|
||||||
|
echo -e "${CYAN}🔍 Поиск последней версии в GitHub (${REPO})...${RESET}"
|
||||||
|
|
||||||
|
RELEASE_JSON=$(curl -s "https://api.github.com/repos/${REPO}/releases/latest" || true)
|
||||||
|
TAG_NAME=$(echo "$RELEASE_JSON" | grep -m1 '"tag_name":' | cut -d '"' -f 4 || true)
|
||||||
|
|
||||||
|
if [ -z "$TAG_NAME" ]; then
|
||||||
|
TAG_NAME="v0.1.5"
|
||||||
|
echo -e "${YELLOW}⚠️ Использована версия по умолчанию: ${TAG_NAME}${RESET}"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}✓ Найдена версия: ${TAG_NAME}${RESET}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. Поиск прямой ссылки на скачивание нужного пакета
|
||||||
|
DOWNLOAD_URL=""
|
||||||
|
case "$PKG_TYPE" in
|
||||||
|
deb)
|
||||||
|
DOWNLOAD_URL=$(echo "$RELEASE_JSON" | grep -o 'https://[^"]*\.deb' | head -n 1 || true)
|
||||||
|
;;
|
||||||
|
rpm)
|
||||||
|
DOWNLOAD_URL=$(echo "$RELEASE_JSON" | grep -o 'https://[^"]*\.rpm' | head -n 1 || true)
|
||||||
|
;;
|
||||||
|
arch|appimage)
|
||||||
|
DOWNLOAD_URL=$(echo "$RELEASE_JSON" | grep -o 'https://[^"]*\.AppImage' | head -n 1 || true)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Запасные прямые URL если GitHub API не вернул ссылки в JSON
|
||||||
|
if [ -z "$DOWNLOAD_URL" ]; then
|
||||||
|
case "$PKG_TYPE" in
|
||||||
|
deb)
|
||||||
|
DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${TAG_NAME}/home-autli-server_${TAG_NAME#v}_amd64.deb"
|
||||||
|
;;
|
||||||
|
rpm)
|
||||||
|
DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${TAG_NAME}/home-autli-server-${TAG_NAME#v}-1.x86_64.rpm"
|
||||||
|
;;
|
||||||
|
arch|appimage)
|
||||||
|
DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${TAG_NAME}/home-autli-server_${TAG_NAME#v}_amd64.AppImage"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
TMP_DIR=$(mktemp -d /tmp/has-install.XXXXXX)
|
||||||
|
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||||
|
|
||||||
|
FILE_NAME=$(basename "$DOWNLOAD_URL")
|
||||||
|
TMP_FILE="$TMP_DIR/$FILE_NAME"
|
||||||
|
|
||||||
|
echo -e "${CYAN}⬇️ Скачивание пакета (${FILE_NAME})...${RESET}"
|
||||||
|
if command -v curl &>/dev/null; then
|
||||||
|
curl -fL --progress-bar "$DOWNLOAD_URL" -o "$TMP_FILE"
|
||||||
|
elif command -v wget &>/dev/null; then
|
||||||
|
wget -q --show-progress "$DOWNLOAD_URL" -O "$TMP_FILE"
|
||||||
|
else
|
||||||
|
echo -e "${RED}Ошибка: необходимо установить curl или wget.${RESET}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ Файл успешно загружен.${RESET}"
|
||||||
|
|
||||||
|
# 5. Установка пакета в систему
|
||||||
|
echo -e "${CYAN}⚙️ Установка ${APP_NAME}...${RESET}"
|
||||||
|
|
||||||
|
case "$PKG_TYPE" in
|
||||||
|
deb)
|
||||||
|
echo -e "${BLUE}Выполняется установка .deb через dpkg / apt...${RESET}"
|
||||||
|
if sudo dpkg -i "$TMP_FILE"; then
|
||||||
|
echo -e "${GREEN}✓ Пакет установлен.${RESET}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}Доустановка недостающих зависимостей...${RESET}"
|
||||||
|
sudo apt-get update -qq
|
||||||
|
sudo apt-get install -f -y
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
rpm)
|
||||||
|
echo -e "${BLUE}Выполняется установка .rpm через dnf / rpm...${RESET}"
|
||||||
|
if command -v dnf &>/dev/null; then
|
||||||
|
sudo dnf install -y "$TMP_FILE"
|
||||||
|
elif command -v yum &>/dev/null; then
|
||||||
|
sudo yum localinstall -y "$TMP_FILE"
|
||||||
|
else
|
||||||
|
sudo rpm -Uvh --replacepkgs "$TMP_FILE"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
arch)
|
||||||
|
echo -e "${BLUE}Настройка для Arch Linux / CachyOS...${RESET}"
|
||||||
|
# Проверка и установка зависимостей через pacman при необходимости
|
||||||
|
if command -v pacman &>/dev/null; then
|
||||||
|
echo -e "${CYAN}Проверка зависимостей (webkit2gtk-4.1, libappindicator-gtk3)...${RESET}"
|
||||||
|
sudo pacman -S --needed --noconfirm webkit2gtk-4.1 libappindicator-gtk3 librsvg || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
chmod +x "$TMP_FILE"
|
||||||
|
INSTALL_BIN="$HOME/.local/bin"
|
||||||
|
mkdir -p "$INSTALL_BIN"
|
||||||
|
mv "$TMP_FILE" "$INSTALL_BIN/$BIN_NAME"
|
||||||
|
|
||||||
|
# Скачивание логотипа HAS для меню CachyOS / Arch
|
||||||
|
ICON_DIR="$HOME/.local/share/icons/hicolor/512x512/apps"
|
||||||
|
mkdir -p "$ICON_DIR"
|
||||||
|
curl -sL "https://raw.githubusercontent.com/${REPO}/main/public/logo.png" -o "$ICON_DIR/has.png" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Создание .desktop файла для меню приложений (KDE Plasma, GNOME, Hyprland, XFCE)
|
||||||
|
DESKTOP_DIR="$HOME/.local/share/applications"
|
||||||
|
mkdir -p "$DESKTOP_DIR"
|
||||||
|
cat <<EOF > "$DESKTOP_DIR/home-autli-server.desktop"
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Home Autli Server
|
||||||
|
Comment=Личный сервер, Кинотеатр (Full HD + Русская озвучка) и Облако
|
||||||
|
Exec=$INSTALL_BIN/$BIN_NAME
|
||||||
|
Icon=$ICON_DIR/has.png
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Categories=AudioVideo;Player;Network;Utility;
|
||||||
|
StartupWMClass=home-autli-server
|
||||||
|
EOF
|
||||||
|
chmod +x "$DESKTOP_DIR/home-autli-server.desktop"
|
||||||
|
echo -e "${GREEN}✓ Исполняемый файл установлен в $INSTALL_BIN/$BIN_NAME${RESET}"
|
||||||
|
echo -e "${GREEN}✓ Ярлык добавлен в меню приложений Arch / CachyOS.${RESET}"
|
||||||
|
;;
|
||||||
|
appimage)
|
||||||
|
echo -e "${BLUE}Настройка переносимого AppImage...${RESET}"
|
||||||
|
chmod +x "$TMP_FILE"
|
||||||
|
INSTALL_BIN="$HOME/.local/bin"
|
||||||
|
mkdir -p "$INSTALL_BIN"
|
||||||
|
mv "$TMP_FILE" "$INSTALL_BIN/$BIN_NAME"
|
||||||
|
|
||||||
|
ICON_DIR="$HOME/.local/share/icons"
|
||||||
|
mkdir -p "$ICON_DIR"
|
||||||
|
curl -sL "https://raw.githubusercontent.com/${REPO}/main/public/logo.png" -o "$ICON_DIR/has.png" 2>/dev/null || true
|
||||||
|
|
||||||
|
DESKTOP_DIR="$HOME/.local/share/applications"
|
||||||
|
mkdir -p "$DESKTOP_DIR"
|
||||||
|
cat <<EOF > "$DESKTOP_DIR/home-autli-server.desktop"
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Home Autli Server
|
||||||
|
Comment=Личный сервер, Кинотеатр и Хранилище
|
||||||
|
Exec=$INSTALL_BIN/$BIN_NAME
|
||||||
|
Icon=$ICON_DIR/has.png
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Categories=AudioVideo;Player;Network;Utility;
|
||||||
|
StartupWMClass=home-autli-server
|
||||||
|
EOF
|
||||||
|
chmod +x "$DESKTOP_DIR/home-autli-server.desktop"
|
||||||
|
echo -e "${GREEN}✓ Исполняемый файл установлен в $INSTALL_BIN/$BIN_NAME${RESET}"
|
||||||
|
echo -e "${GREEN}✓ Ярлык добавлен в меню приложений.${RESET}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}${BOLD}==========================================================${RESET}"
|
||||||
|
echo -e "${GREEN}${BOLD} 🎉 ${APP_NAME} успешно установлен на ваш Linux! ${RESET}"
|
||||||
|
echo -e "${GREEN}${BOLD}==========================================================${RESET}"
|
||||||
|
echo ""
|
||||||
|
echo -e "Вы можете запустить приложение:"
|
||||||
|
echo -e " 1. Из меню приложений вашего рабочего стола: ${BOLD}Home Autli Server${RESET}"
|
||||||
|
echo -e " 2. Или прямо в терминале командой: ${CYAN}${BOLD}has${RESET}"
|
||||||
|
echo ""
|
||||||
1215
package-lock.json
generated
Normal file
31
package.json
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"name": "has",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.1",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "tsc && vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"tauri": "tauri",
|
||||||
|
"android": "./scripts/run-android.sh dev",
|
||||||
|
"android:build": "./scripts/run-android.sh build --apk"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@tauri-apps/api": "^2",
|
||||||
|
"@tauri-apps/plugin-opener": "^2",
|
||||||
|
"@tauri-apps/plugin-process": "^2.4.0",
|
||||||
|
"@tauri-apps/plugin-updater": "^2.13.3",
|
||||||
|
"hls.js": "^1.7.3",
|
||||||
|
"react": "^19.1.0",
|
||||||
|
"react-dom": "^19.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tauri-apps/cli": "^2",
|
||||||
|
"@types/react": "^19.1.8",
|
||||||
|
"@types/react-dom": "^19.1.6",
|
||||||
|
"@vitejs/plugin-react": "^6.0.2",
|
||||||
|
"typescript": "~6.0.3",
|
||||||
|
"vite": "^8.0.16"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/logo.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
6
public/tauri.svg
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
<svg width="206" height="231" viewBox="0 0 206 231" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M143.143 84C143.143 96.1503 133.293 106 121.143 106C108.992 106 99.1426 96.1503 99.1426 84C99.1426 71.8497 108.992 62 121.143 62C133.293 62 143.143 71.8497 143.143 84Z" fill="#FFC131"/>
|
||||||
|
<ellipse cx="84.1426" cy="147" rx="22" ry="22" transform="rotate(180 84.1426 147)" fill="#24C8DB"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M166.738 154.548C157.86 160.286 148.023 164.269 137.757 166.341C139.858 160.282 141 153.774 141 147C141 144.543 140.85 142.121 140.558 139.743C144.975 138.204 149.215 136.139 153.183 133.575C162.73 127.404 170.292 118.608 174.961 108.244C179.63 97.8797 181.207 86.3876 179.502 75.1487C177.798 63.9098 172.884 53.4021 165.352 44.8883C157.82 36.3744 147.99 30.2165 137.042 27.1546C126.095 24.0926 114.496 24.2568 103.64 27.6274C92.7839 30.998 83.1319 37.4317 75.8437 46.1553C74.9102 47.2727 74.0206 48.4216 73.176 49.5993C61.9292 50.8488 51.0363 54.0318 40.9629 58.9556C44.2417 48.4586 49.5653 38.6591 56.679 30.1442C67.0505 17.7298 80.7861 8.57426 96.2354 3.77762C111.685 -1.01901 128.19 -1.25267 143.769 3.10474C159.348 7.46215 173.337 16.2252 184.056 28.3411C194.775 40.457 201.767 55.4101 204.193 71.404C206.619 87.3978 204.374 103.752 197.73 118.501C191.086 133.25 180.324 145.767 166.738 154.548ZM41.9631 74.275L62.5557 76.8042C63.0459 72.813 63.9401 68.9018 65.2138 65.1274C57.0465 67.0016 49.2088 70.087 41.9631 74.275Z" fill="#FFC131"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M38.4045 76.4519C47.3493 70.6709 57.2677 66.6712 67.6171 64.6132C65.2774 70.9669 64 77.8343 64 85.0001C64 87.1434 64.1143 89.26 64.3371 91.3442C60.0093 92.8732 55.8533 94.9092 51.9599 97.4256C42.4128 103.596 34.8505 112.392 30.1816 122.756C25.5126 133.12 23.9357 144.612 25.6403 155.851C27.3449 167.09 32.2584 177.598 39.7906 186.112C47.3227 194.626 57.153 200.784 68.1003 203.846C79.0476 206.907 90.6462 206.743 101.502 203.373C112.359 200.002 122.011 193.568 129.299 184.845C130.237 183.722 131.131 182.567 131.979 181.383C143.235 180.114 154.132 176.91 164.205 171.962C160.929 182.49 155.596 192.319 148.464 200.856C138.092 213.27 124.357 222.426 108.907 227.222C93.458 232.019 76.9524 232.253 61.3736 227.895C45.7948 223.538 31.8055 214.775 21.0867 202.659C10.3679 190.543 3.37557 175.59 0.949823 159.596C-1.47592 143.602 0.768139 127.248 7.41237 112.499C14.0566 97.7497 24.8183 85.2327 38.4045 76.4519ZM163.062 156.711L163.062 156.711C162.954 156.773 162.846 156.835 162.738 156.897C162.846 156.835 162.954 156.773 163.062 156.711Z" fill="#24C8DB"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
1
public/vite.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
26
scripts/run-android.sh
Executable file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
cd "$DIR"
|
||||||
|
|
||||||
|
export ANDROID_HOME="${ANDROID_HOME:-$HOME/Library/Android/sdk}"
|
||||||
|
if [ -z "$NDK_HOME" ]; then
|
||||||
|
if [ -d "$ANDROID_HOME/ndk/27.2.12479018" ]; then
|
||||||
|
export NDK_HOME="$ANDROID_HOME/ndk/27.2.12479018"
|
||||||
|
elif [ -d "$ANDROID_HOME/ndk" ]; then
|
||||||
|
export NDK_HOME="$(ls -d "$ANDROID_HOME/ndk/"* 2>/dev/null | tail -n 1)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$NDK_HOME" ] && [ -d "$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin" ]; then
|
||||||
|
TOOLCHAIN_BIN="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin"
|
||||||
|
export PATH="$TOOLCHAIN_BIN:/usr/local/bin:/opt/homebrew/bin:$PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export OPENSSL_STATIC=1
|
||||||
|
export AR_aarch64_linux_android=llvm-ar
|
||||||
|
export RANLIB_aarch64_linux_android=llvm-ranlib
|
||||||
|
export RUSTFLAGS="-C link-arg=-Wl,-z,max-page-size=16384 ${RUSTFLAGS:-}"
|
||||||
|
|
||||||
|
exec npx tauri android "$@"
|
||||||
191
scripts/server-anti-ddos.sh
Executable file
|
|
@ -0,0 +1,191 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# ==============================================================================
|
||||||
|
# HAS Server Anti-DDoS & Port 5432 Protection Setup Script
|
||||||
|
# ==============================================================================
|
||||||
|
# This script hardens Ubuntu server against:
|
||||||
|
# 1. TCP SYN Flood & Connection Exhaustion DDoS
|
||||||
|
# 2. Port 5432 Port Scanning, Connection Floods & Slowloris
|
||||||
|
# 3. PostgreSQL Brute-Force & Credential Stuffing
|
||||||
|
# 4. Kernel Socket & Memory Exhaustion Attacks
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Color output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo -e "${BLUE}====================================================================${NC}"
|
||||||
|
echo -e "${BLUE} HAS SERVER ANTI-DDOS & PORT 5432 HARDENING SETUP ${NC}"
|
||||||
|
echo -e "${BLUE}====================================================================${NC}"
|
||||||
|
|
||||||
|
# 1. Check Root
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
echo -e "${RED}❌ Пожалуйста, запустите скрипт с правами суперпользователя: sudo bash $0${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\n${YELLOW}>>> 1/5. Настройка ядра Linux против SYN Flood и DoS атак...${NC}"
|
||||||
|
|
||||||
|
SYSCTL_CONF="/etc/sysctl.d/99-has-anti-ddos.conf"
|
||||||
|
cat << 'EOF' > "$SYSCTL_CONF"
|
||||||
|
# --- HAS Anti-DDoS Kernel Protection ---
|
||||||
|
# 1. SYN Flood Protection (Cryptographic SYN cookies when queue is under attack)
|
||||||
|
net.ipv4.tcp_syncookies = 1
|
||||||
|
net.ipv4.tcp_max_syn_backlog = 8192
|
||||||
|
net.ipv4.tcp_synack_retries = 2
|
||||||
|
net.ipv4.tcp_syn_retries = 3
|
||||||
|
|
||||||
|
# 2. Fast timeout for abandoned and dead connections (Anti-Slowloris)
|
||||||
|
net.ipv4.tcp_fin_timeout = 15
|
||||||
|
net.ipv4.tcp_keepalive_time = 30
|
||||||
|
net.ipv4.tcp_keepalive_intvl = 10
|
||||||
|
net.ipv4.tcp_keepalive_probes = 3
|
||||||
|
|
||||||
|
# 3. Socket reuse & connection scaling
|
||||||
|
net.ipv4.tcp_tw_reuse = 1
|
||||||
|
net.core.somaxconn = 4096
|
||||||
|
net.core.netdev_max_backlog = 5000
|
||||||
|
net.ipv4.ip_local_port_range = 1024 65535
|
||||||
|
|
||||||
|
# 4. Anti-Spoofing & Broadcast ICMP flood protection
|
||||||
|
net.ipv4.conf.all.rp_filter = 1
|
||||||
|
net.ipv4.conf.default.rp_filter = 1
|
||||||
|
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||||||
|
net.ipv4.icmp_ignore_bogus_error_responses = 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sysctl -p "$SYSCTL_CONF" >/dev/null 2>&1 || sysctl --system >/dev/null 2>&1
|
||||||
|
echo -e "${GREEN}✓ Параметры ядра sysctl применены: SYN-cookies включены, таймауты сброшены.${NC}"
|
||||||
|
|
||||||
|
# 2. Iptables Rate-Limiting & Connection Limits on Port 5432
|
||||||
|
echo -e "\n${YELLOW}>>> 2/5. Настройка фаервола iptables на порту 5432...${NC}"
|
||||||
|
|
||||||
|
# Ensure iptables-persistent is installed
|
||||||
|
if ! command -v iptables &> /dev/null; then
|
||||||
|
apt-get update -y && apt-get install -y iptables
|
||||||
|
fi
|
||||||
|
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
apt-get install -y iptables-persistent netfilter-persistent >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
# Remove older duplicate HAS rules if any
|
||||||
|
iptables -D INPUT -p tcp --dport 5432 -m connlimit --connlimit-above 10 --connlimit-mask 32 -j REJECT --reject-with tcp-reset 2>/dev/null || true
|
||||||
|
iptables -D INPUT -p tcp --dport 5432 -m state --state NEW -m recent --update --seconds 10 --hitcount 20 --name HAS_PG_RATE -j DROP 2>/dev/null || true
|
||||||
|
iptables -D INPUT -p tcp --dport 5432 -m state --state NEW -m recent --set --name HAS_PG_RATE 2>/dev/null || true
|
||||||
|
iptables -D INPUT -p tcp --dport 5432 --syn -m limit --limit 30/s --limit-burst 60 -j ACCEPT 2>/dev/null || true
|
||||||
|
|
||||||
|
# RULE A: Limit max concurrent connections per single IP to 10
|
||||||
|
# (Real app uses 1-3 connections; botnet opening 50+ sockets gets immediate TCP RST)
|
||||||
|
iptables -I INPUT -p tcp --dport 5432 -m connlimit --connlimit-above 10 --connlimit-mask 32 -j REJECT --reject-with tcp-reset
|
||||||
|
|
||||||
|
# RULE B: Rate-limit new connections (Anti-Scan / Anti-Burst Flood)
|
||||||
|
# (Max 20 new connections per 10 seconds per IP, rest are dropped silently)
|
||||||
|
iptables -I INPUT -p tcp --dport 5432 -m state --state NEW -m recent --update --seconds 10 --hitcount 20 --name HAS_PG_RATE -j DROP
|
||||||
|
iptables -I INPUT -p tcp --dport 5432 -m state --state NEW -m recent --set --name HAS_PG_RATE
|
||||||
|
|
||||||
|
# RULE C: SYN flood packet rate limiting
|
||||||
|
iptables -I INPUT -p tcp --dport 5432 --syn -m limit --limit 30/s --limit-burst 60 -j ACCEPT
|
||||||
|
|
||||||
|
# Save iptables rules to persist across reboot
|
||||||
|
if command -v netfilter-persistent &> /dev/null; then
|
||||||
|
netfilter-persistent save >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
mkdir -p /etc/iptables
|
||||||
|
iptables-save > /etc/iptables/rules.v4 2>/dev/null || true
|
||||||
|
echo -e "${GREEN}✓ Iptables настроен: макс. 10 подключений на 1 IP, лимит новых сессий (20/10с), защита от SYN-flood.${NC}"
|
||||||
|
|
||||||
|
# 3. Hardening PostgreSQL Server (postgresql.conf)
|
||||||
|
echo -e "\n${YELLOW}>>> 3/5. Оптимизация параметров безопасности PostgreSQL...${NC}"
|
||||||
|
|
||||||
|
PG_CONF=""
|
||||||
|
for p in "/www/server/pgsql/data/postgresql.conf" $(find /etc/postgresql -name postgresql.conf 2>/dev/null); do
|
||||||
|
if [ -f "$p" ]; then
|
||||||
|
PG_CONF="$p"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$PG_CONF" ] && [ -f "$PG_CONF" ]; then
|
||||||
|
echo -e "Найден конфигурационный файл: ${BLUE}$PG_CONF${NC}"
|
||||||
|
cp "$PG_CONF" "${PG_CONF}.bak_$(date +%Y%m%d%H%M%S)"
|
||||||
|
|
||||||
|
# Anti-Slowloris: reduce authentication timeout from 60s to 5s
|
||||||
|
sed -i "s/^#\?authentication_timeout\s*=.*/authentication_timeout = 5s/" "$PG_CONF"
|
||||||
|
|
||||||
|
# Fast keepalive for dead client connections
|
||||||
|
sed -i "s/^#\?tcp_keepalives_idle\s*=.*/tcp_keepalives_idle = 15/" "$PG_CONF"
|
||||||
|
sed -i "s/^#\?tcp_keepalives_interval\s*=.*/tcp_keepalives_interval = 5/" "$PG_CONF"
|
||||||
|
sed -i "s/^#\?tcp_keepalives_count\s*=.*/tcp_keepalives_count = 3/" "$PG_CONF"
|
||||||
|
|
||||||
|
# Connection limits & admin reservation
|
||||||
|
sed -i "s/^#\?max_connections\s*=.*/max_connections = 120/" "$PG_CONF"
|
||||||
|
sed -i "s/^#\?superuser_reserved_connections\s*=.*/superuser_reserved_connections = 5/" "$PG_CONF"
|
||||||
|
|
||||||
|
# Reload PostgreSQL configuration without downtime
|
||||||
|
if [ -f "/www/server/pgsql/bin/pg_ctl" ]; then
|
||||||
|
su - postgres -c "/www/server/pgsql/bin/pg_ctl -D /www/server/pgsql/data reload" >/dev/null 2>&1 || true
|
||||||
|
elif [ -f "/etc/init.d/pgsql" ]; then
|
||||||
|
/etc/init.d/pgsql reload >/dev/null 2>&1 || true
|
||||||
|
else
|
||||||
|
systemctl reload postgresql >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
echo -e "${GREEN}✓ PostgreSQL обновлен: authentication_timeout=5s (Anti-Slowloris), keepalive=15s, резерв для админа.${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}⚠️ Файл postgresql.conf не найден автоматически, пропуск обновления параметров PG.${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. Setup Fail2Ban against Brute-Force & Malicious Scanners
|
||||||
|
echo -e "\n${YELLOW}>>> 4/5. Настройка Fail2ban для автоматической блокировки атакующих ботов...${NC}"
|
||||||
|
|
||||||
|
apt-get update -y >/dev/null 2>&1 || true
|
||||||
|
apt-get install -y fail2ban >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
if command -v fail2ban-client &> /dev/null; then
|
||||||
|
mkdir -p /etc/fail2ban/filter.d /etc/fail2ban/jail.d
|
||||||
|
|
||||||
|
cat << 'EOF' > /etc/fail2ban/filter.d/postgresql-has.conf
|
||||||
|
[Definition]
|
||||||
|
failregex = ^.*FATAL:\s+password authentication failed for user.*host=<HOST>.*$
|
||||||
|
^.*FATAL:\s+no pg_hba.conf entry for host "<HOST>".*$
|
||||||
|
ignoreregex =
|
||||||
|
EOF
|
||||||
|
|
||||||
|
PG_LOG="/www/server/pgsql/data/server.log"
|
||||||
|
if [ ! -f "$PG_LOG" ]; then
|
||||||
|
PG_LOG="/var/log/postgresql/postgresql-*.log"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat << EOF > /etc/fail2ban/jail.d/postgresql-has.local
|
||||||
|
[postgresql-has]
|
||||||
|
enabled = true
|
||||||
|
port = 5432
|
||||||
|
filter = postgresql-has
|
||||||
|
logpath = $PG_LOG
|
||||||
|
maxretry = 5
|
||||||
|
findtime = 600
|
||||||
|
bantime = 86400
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl restart fail2ban >/dev/null 2>&1 || service fail2ban restart >/dev/null 2>&1 || true
|
||||||
|
echo -e "${GREEN}✓ Fail2ban активирован: автобан на 24 часа при 5 неудачных попытках авторизации.${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}⚠️ Fail2ban не удалось установить автоматически.${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 5. Verification & Status Output
|
||||||
|
echo -e "\n${BLUE}====================================================================${NC}"
|
||||||
|
echo -e "${GREEN}🎉 НАСТРОЙКА ЗАЩИТЫ УСПЕШНО ЗАВЕРШЕНА!${NC}"
|
||||||
|
echo -e "${BLUE}====================================================================${NC}"
|
||||||
|
echo -e "Активные правила iptables на порту 5432:"
|
||||||
|
iptables -L INPUT -v -n --line-numbers | grep -E "5432|dpt" || true
|
||||||
|
|
||||||
|
echo -e "\n${YELLOW}Полезные команды для мониторинга сервера:${NC}"
|
||||||
|
echo -e "1. Просмотр заблокированных ботов в Fail2ban: ${GREEN}fail2ban-client status postgresql-has${NC}"
|
||||||
|
echo -e "2. Просмотр счетчика отброшенных пакетов: ${GREEN}iptables -L INPUT -v -n | grep 5432${NC}"
|
||||||
|
echo -e "3. Просмотр активных соединений с базой: ${GREEN}ss -nt state established '( sport = :5432 )'${NC}"
|
||||||
|
echo -e "4. Разблокировать ошибочно забаненный IP: ${GREEN}fail2ban-client set postgresql-has unbanip <IP>${NC}"
|
||||||
|
echo -e "${BLUE}====================================================================${NC}"
|
||||||
26
scripts/setup-android-env.sh
Executable file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ANDROID_HOME="${ANDROID_HOME:-$HOME/Library/Android/sdk}"
|
||||||
|
if [ -z "$NDK_HOME" ]; then
|
||||||
|
if [ -d "$ANDROID_HOME/ndk/27.2.12479018" ]; then
|
||||||
|
NDK_HOME="$ANDROID_HOME/ndk/27.2.12479018"
|
||||||
|
elif [ -d "$ANDROID_HOME/ndk" ]; then
|
||||||
|
NDK_HOME="$(ls -d "$ANDROID_HOME/ndk/"* 2>/dev/null | tail -n 1)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$NDK_HOME" ] && [ -d "$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin" ]; then
|
||||||
|
TOOLCHAIN_BIN="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin"
|
||||||
|
echo "Setting up GNU binutils symlinks in $TOOLCHAIN_BIN..."
|
||||||
|
for prefix in aarch64-linux-android arm-linux-androideabi armv7a-linux-androideabi x86_64-linux-android i686-linux-android; do
|
||||||
|
[ -f "$TOOLCHAIN_BIN/llvm-ar" ] && ln -sf "$TOOLCHAIN_BIN/llvm-ar" "$TOOLCHAIN_BIN/${prefix}-ar"
|
||||||
|
[ -f "$TOOLCHAIN_BIN/llvm-ranlib" ] && ln -sf "$TOOLCHAIN_BIN/llvm-ranlib" "$TOOLCHAIN_BIN/${prefix}-ranlib"
|
||||||
|
[ -f "$TOOLCHAIN_BIN/llvm-nm" ] && ln -sf "$TOOLCHAIN_BIN/llvm-nm" "$TOOLCHAIN_BIN/${prefix}-nm"
|
||||||
|
[ -f "$TOOLCHAIN_BIN/llvm-as" ] && ln -sf "$TOOLCHAIN_BIN/llvm-as" "$TOOLCHAIN_BIN/${prefix}-as"
|
||||||
|
[ -f "$TOOLCHAIN_BIN/llvm-strip" ] && ln -sf "$TOOLCHAIN_BIN/llvm-strip" "$TOOLCHAIN_BIN/${prefix}-strip"
|
||||||
|
done
|
||||||
|
echo "Symlinks created successfully."
|
||||||
|
else
|
||||||
|
echo "NDK toolchain not found at $NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin"
|
||||||
|
fi
|
||||||
11
src-tauri/.cargo/config.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
[target.aarch64-linux-android]
|
||||||
|
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]
|
||||||
|
|
||||||
|
[target.armv7-linux-androideabi]
|
||||||
|
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]
|
||||||
|
|
||||||
|
[target.x86_64-linux-android]
|
||||||
|
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]
|
||||||
|
|
||||||
|
[target.i686-linux-android]
|
||||||
|
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]
|
||||||
7
src-tauri/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Generated by Cargo
|
||||||
|
# will have compiled files and executables
|
||||||
|
/target/
|
||||||
|
|
||||||
|
# Generated by Tauri
|
||||||
|
# will have schema files for capabilities auto-completion
|
||||||
|
/gen/schemas
|
||||||
5838
src-tauri/Cargo.lock
generated
Normal file
50
src-tauri/Cargo.toml
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
[package]
|
||||||
|
name = "has"
|
||||||
|
version = "0.0.1"
|
||||||
|
description = "has"
|
||||||
|
authors = ["autli"]
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
# The `_lib` suffix may seem redundant but it is necessary
|
||||||
|
# to make the lib name unique and wouldn't conflict with the bin name.
|
||||||
|
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
|
||||||
|
name = "has_lib"
|
||||||
|
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
tauri-build = { version = "2", features = [] }
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tauri = { version = "2", features = [] }
|
||||||
|
tauri-plugin-opener = "2"
|
||||||
|
tauri-plugin-updater = "2"
|
||||||
|
tauri-plugin-process = "2"
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
serde_json = "1"
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
tokio-postgres = { version = "0.7", features = ["with-chrono-0_4"] }
|
||||||
|
native-tls = { version = "0.2", features = ["vendored"] }
|
||||||
|
openssl = { version = "0.10", features = ["vendored"] }
|
||||||
|
tokio-native-tls = "0.3"
|
||||||
|
postgres-native-tls = "0.5"
|
||||||
|
dotenvy = "0.15"
|
||||||
|
bcrypt = "0.17"
|
||||||
|
sha2 = "0.10"
|
||||||
|
hex = "0.4"
|
||||||
|
base64 = "0.22"
|
||||||
|
chrono = { version = "0.4", default-features = false, features = ["clock"] }
|
||||||
|
reqwest = { version = "0.12", default-features = false, features = ["json", "default-tls"] }
|
||||||
|
rustls = { version = "0.23", default-features = false, features = ["ring"] }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Read the optimization guideline for more details: https://tauri.app/concept/size/#cargo-configuration
|
||||||
|
[profile.release]
|
||||||
|
codegen-units = 1
|
||||||
|
lto = true
|
||||||
|
opt-level = 3
|
||||||
|
panic = "abort"
|
||||||
|
strip = true
|
||||||
3
src-tauri/build.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
tauri_build::build()
|
||||||
|
}
|
||||||
12
src-tauri/capabilities/default.json
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"$schema": "../gen/schemas/desktop-schema.json",
|
||||||
|
"identifier": "default",
|
||||||
|
"description": "Capability for the main window",
|
||||||
|
"windows": ["main"],
|
||||||
|
"permissions": [
|
||||||
|
"core:default",
|
||||||
|
"opener:default",
|
||||||
|
"updater:default",
|
||||||
|
"process:default"
|
||||||
|
]
|
||||||
|
}
|
||||||
12
src-tauri/gen/android/.editorconfig
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
# EditorConfig is awesome: https://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
insert_final_newline = false
|
||||||
20
src-tauri/gen/android/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/caches
|
||||||
|
/.idea/libraries
|
||||||
|
/.idea/modules.xml
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/navEditor.xml
|
||||||
|
/.idea/assetWizardSettings.xml
|
||||||
|
.DS_Store
|
||||||
|
build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
|
.cxx
|
||||||
|
local.properties
|
||||||
|
key.properties
|
||||||
|
keystore.properties
|
||||||
|
|
||||||
|
/.tauri
|
||||||
|
/tauri.settings.gradle
|
||||||
6
src-tauri/gen/android/app/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
/src/main/**/generated
|
||||||
|
/src/main/jniLibs/**/*.so
|
||||||
|
/src/main/assets/tauri.conf.json
|
||||||
|
/tauri.build.gradle.kts
|
||||||
|
/proguard-tauri.pro
|
||||||
|
/tauri.properties
|
||||||
84
src-tauri/gen/android/app/build.gradle.kts
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
import java.util.Properties
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("com.android.application")
|
||||||
|
id("org.jetbrains.kotlin.android")
|
||||||
|
id("rust")
|
||||||
|
}
|
||||||
|
|
||||||
|
val tauriProperties = Properties().apply {
|
||||||
|
val propFile = file("tauri.properties")
|
||||||
|
if (propFile.exists()) {
|
||||||
|
propFile.inputStream().use { load(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdk = 37
|
||||||
|
namespace = "com.has.tauri_app"
|
||||||
|
defaultConfig {
|
||||||
|
manifestPlaceholders["usesCleartextTraffic"] = "false"
|
||||||
|
applicationId = "com.has.tauri_app"
|
||||||
|
minSdk = 24
|
||||||
|
targetSdk = 37
|
||||||
|
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
|
||||||
|
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
getByName("debug") {
|
||||||
|
manifestPlaceholders["usesCleartextTraffic"] = "true"
|
||||||
|
isDebuggable = true
|
||||||
|
isJniDebuggable = true
|
||||||
|
isMinifyEnabled = false
|
||||||
|
packaging {
|
||||||
|
jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
|
||||||
|
jniLibs.keepDebugSymbols.add("*/armeabi-v7a/*.so")
|
||||||
|
jniLibs.keepDebugSymbols.add("*/x86/*.so")
|
||||||
|
jniLibs.keepDebugSymbols.add("*/x86_64/*.so")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getByName("release") {
|
||||||
|
signingConfig = signingConfigs.getByName("debug")
|
||||||
|
optimization {
|
||||||
|
enable = true
|
||||||
|
}
|
||||||
|
proguardFiles(
|
||||||
|
*fileTree(".") {
|
||||||
|
include("**/*.pro")
|
||||||
|
exclude("build/**")
|
||||||
|
}.files.toTypedArray()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
buildFeatures {
|
||||||
|
buildConfig = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
compilerOptions {
|
||||||
|
jvmTarget = JvmTarget.JVM_1_8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rust {
|
||||||
|
rootDirRel = "../../../"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("androidx.webkit:webkit:1.14.0")
|
||||||
|
implementation("androidx.appcompat:appcompat:1.7.1")
|
||||||
|
implementation("androidx.activity:activity-ktx:1.10.1")
|
||||||
|
implementation("com.google.android.material:material:1.12.0")
|
||||||
|
implementation("androidx.lifecycle:lifecycle-process:2.10.0")
|
||||||
|
testImplementation("junit:junit:4.13.2")
|
||||||
|
androidTestImplementation("androidx.test.ext:junit:1.1.4")
|
||||||
|
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(from = file("tauri.build.gradle.kts"))
|
||||||
21
src-tauri/gen/android/app/proguard-rules.pro
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
38
src-tauri/gen/android/app/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
|
<!-- AndroidTV support -->
|
||||||
|
<uses-feature android:name="android.software.leanback" android:required="false" />
|
||||||
|
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/Theme.tauri_app"
|
||||||
|
android:usesCleartextTraffic="${usesCleartextTraffic}">
|
||||||
|
<activity
|
||||||
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:label="@string/main_activity_title"
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
<!-- AndroidTV support -->
|
||||||
|
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
android:authorities="${applicationId}.fileprovider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/file_paths" />
|
||||||
|
</provider>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.has.tauri_app
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
|
||||||
|
class MainActivity : TauriActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
enableEdgeToEdge()
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="85.84757"
|
||||||
|
android:endY="92.4963"
|
||||||
|
android:startX="42.9492"
|
||||||
|
android:startY="49.59793"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0" />
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0" />
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:strokeColor="#00000000" />
|
||||||
|
</vector>
|
||||||
|
|
@ -0,0 +1,170 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path
|
||||||
|
android:fillColor="#3DDC84"
|
||||||
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M9,0L9,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,0L19,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,0L29,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,0L39,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,0L49,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,0L59,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,0L69,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,0L79,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M89,0L89,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M99,0L99,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,9L108,9"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,19L108,19"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,29L108,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,39L108,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,49L108,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,59L108,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,69L108,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,79L108,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,89L108,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,99L108,99"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,29L89,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,39L89,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,49L89,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,59L89,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,69L89,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,79L89,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,19L29,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,19L39,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,19L49,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,19L59,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,19L69,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,19L79,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
</vector>
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Hello World!"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -0,0 +1,6 @@
|
||||||
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="Theme.tauri_app" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
|
<!-- Customize your theme here. -->
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
10
src-tauri/gen/android/app/src/main/res/values/colors.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="purple_200">#FFBB86FC</color>
|
||||||
|
<color name="purple_500">#FF6200EE</color>
|
||||||
|
<color name="purple_700">#FF3700B3</color>
|
||||||
|
<color name="teal_200">#FF03DAC5</color>
|
||||||
|
<color name="teal_700">#FF018786</color>
|
||||||
|
<color name="black">#FF000000</color>
|
||||||
|
<color name="white">#FFFFFFFF</color>
|
||||||
|
</resources>
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">"Home Autli Server"</string>
|
||||||
|
<string name="main_activity_title">"Home Autli Server"</string>
|
||||||
|
</resources>
|
||||||
6
src-tauri/gen/android/app/src/main/res/values/themes.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="Theme.tauri_app" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
|
<!-- Customize your theme here. -->
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<external-path name="my_images" path="." />
|
||||||
|
<cache-path name="my_cache_images" path="." />
|
||||||
|
</paths>
|
||||||
22
src-tauri/gen/android/build.gradle.kts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath("com.android.tools.build:gradle:9.4.1")
|
||||||
|
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.10")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register("clean").configure {
|
||||||
|
delete("build")
|
||||||
|
}
|
||||||
|
|
||||||
23
src-tauri/gen/android/buildSrc/build.gradle.kts
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
plugins {
|
||||||
|
`kotlin-dsl`
|
||||||
|
}
|
||||||
|
|
||||||
|
gradlePlugin {
|
||||||
|
plugins {
|
||||||
|
create("pluginsForCoolKids") {
|
||||||
|
id = "rust"
|
||||||
|
implementationClass = "RustPlugin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly(gradleApi())
|
||||||
|
implementation("com.android.tools.build:gradle:9.4.1")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
import java.io.File
|
||||||
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
import org.gradle.api.DefaultTask
|
||||||
|
import org.gradle.api.GradleException
|
||||||
|
import org.gradle.api.logging.LogLevel
|
||||||
|
import org.gradle.api.tasks.Input
|
||||||
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
import javax.inject.Inject
|
||||||
|
import org.gradle.process.ExecOperations
|
||||||
|
|
||||||
|
abstract class BuildTask : DefaultTask() {
|
||||||
|
@get:Inject
|
||||||
|
abstract val execOperations: ExecOperations
|
||||||
|
|
||||||
|
@Input
|
||||||
|
var rootDirRel: String? = null
|
||||||
|
@Input
|
||||||
|
var projectDir: String? = null
|
||||||
|
@Input
|
||||||
|
var target: String? = null
|
||||||
|
@Input
|
||||||
|
var release: Boolean? = null
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun assemble() {
|
||||||
|
val candidates = listOf(
|
||||||
|
"/usr/local/bin/npm",
|
||||||
|
"/opt/homebrew/bin/npm",
|
||||||
|
System.getProperty("user.home") + "/.nvm/versions/node/$(node -v)/bin/npm",
|
||||||
|
"npm"
|
||||||
|
)
|
||||||
|
val executable = candidates.firstOrNull { File(it).exists() } ?: "npm"
|
||||||
|
try {
|
||||||
|
runTauriCli(executable)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||||
|
// Try different Windows-specific extensions
|
||||||
|
val fallbacks = listOf(
|
||||||
|
"$executable.exe",
|
||||||
|
"$executable.cmd",
|
||||||
|
"$executable.bat",
|
||||||
|
)
|
||||||
|
|
||||||
|
var lastException: Exception = e
|
||||||
|
for (fallback in fallbacks) {
|
||||||
|
try {
|
||||||
|
runTauriCli(fallback)
|
||||||
|
return
|
||||||
|
} catch (fallbackException: Exception) {
|
||||||
|
lastException = fallbackException
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw lastException
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runTauriCli(executable: String) {
|
||||||
|
val rootDirRel = rootDirRel ?: throw GradleException("rootDirRel cannot be null")
|
||||||
|
val target = target ?: throw GradleException("target cannot be null")
|
||||||
|
val release = release ?: throw GradleException("release cannot be null")
|
||||||
|
val args = listOf("run", "--", "tauri", "android", "android-studio-script");
|
||||||
|
|
||||||
|
val userHome = System.getProperty("user.home")
|
||||||
|
val androidSdk = File(userHome, "Library/Android/sdk")
|
||||||
|
val ndkDir = File(androidSdk, "ndk/27.2.12479018")
|
||||||
|
val toolchainBin = File(ndkDir, "toolchains/llvm/prebuilt/darwin-x86_64/bin")
|
||||||
|
|
||||||
|
execOperations.exec {
|
||||||
|
workingDir(File(projectDir, rootDirRel))
|
||||||
|
executable(executable)
|
||||||
|
args(args)
|
||||||
|
if (androidSdk.exists()) {
|
||||||
|
environment("ANDROID_HOME", androidSdk.absolutePath)
|
||||||
|
}
|
||||||
|
if (ndkDir.exists()) {
|
||||||
|
environment("NDK_HOME", ndkDir.absolutePath)
|
||||||
|
}
|
||||||
|
val existingPath = System.getenv("PATH") ?: "/usr/bin:/bin:/usr/sbin:/sbin"
|
||||||
|
val fullPath = "${toolchainBin.absolutePath}:/usr/local/bin:/opt/homebrew/bin:$existingPath"
|
||||||
|
environment("PATH", fullPath)
|
||||||
|
environment("OPENSSL_STATIC", "1")
|
||||||
|
environment("AR_aarch64_linux_android", "llvm-ar")
|
||||||
|
environment("RANLIB_aarch64_linux_android", "llvm-ranlib")
|
||||||
|
environment("RUSTFLAGS", "-C link-arg=-Wl,-z,max-page-size=16384")
|
||||||
|
if (logger.isEnabled(LogLevel.DEBUG)) {
|
||||||
|
args("-vv")
|
||||||
|
} else if (logger.isEnabled(LogLevel.INFO)) {
|
||||||
|
args("-v")
|
||||||
|
}
|
||||||
|
if (release) {
|
||||||
|
args("--release")
|
||||||
|
}
|
||||||
|
args(listOf("--target", target))
|
||||||
|
}.assertNormalExitValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
import com.android.build.api.dsl.ApplicationExtension
|
||||||
|
import org.gradle.api.DefaultTask
|
||||||
|
import org.gradle.api.Plugin
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.kotlin.dsl.configure
|
||||||
|
import org.gradle.kotlin.dsl.get
|
||||||
|
|
||||||
|
const val TASK_GROUP = "rust"
|
||||||
|
|
||||||
|
open class Config {
|
||||||
|
lateinit var rootDirRel: String
|
||||||
|
}
|
||||||
|
|
||||||
|
open class RustPlugin : Plugin<Project> {
|
||||||
|
private lateinit var config: Config
|
||||||
|
|
||||||
|
override fun apply(project: Project) = with(project) {
|
||||||
|
config = extensions.create("rust", Config::class.java)
|
||||||
|
|
||||||
|
val defaultAbiList = listOf("arm64-v8a", "armeabi-v7a", "x86", "x86_64");
|
||||||
|
val abiList = (findProperty("abiList") as? String)?.split(',') ?: defaultAbiList
|
||||||
|
|
||||||
|
val defaultArchList = listOf("arm64", "arm", "x86", "x86_64");
|
||||||
|
val archList = (findProperty("archList") as? String)?.split(',') ?: defaultArchList
|
||||||
|
|
||||||
|
val targetsList = (findProperty("targetList") as? String)?.split(',') ?: listOf("aarch64", "armv7", "i686", "x86_64")
|
||||||
|
|
||||||
|
extensions.configure<ApplicationExtension> {
|
||||||
|
@Suppress("UnstableApiUsage")
|
||||||
|
flavorDimensions.add("abi")
|
||||||
|
productFlavors {
|
||||||
|
create("universal") {
|
||||||
|
dimension = "abi"
|
||||||
|
ndk {
|
||||||
|
abiFilters += abiList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defaultArchList.forEachIndexed { index, arch ->
|
||||||
|
create(arch) {
|
||||||
|
dimension = "abi"
|
||||||
|
ndk {
|
||||||
|
abiFilters.add(defaultAbiList[index])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
afterEvaluate {
|
||||||
|
for (profile in listOf("debug", "release")) {
|
||||||
|
val profileCapitalized = profile.replaceFirstChar { it.uppercase() }
|
||||||
|
val buildTask = tasks.maybeCreate(
|
||||||
|
"rustBuildUniversal$profileCapitalized",
|
||||||
|
DefaultTask::class.java
|
||||||
|
).apply {
|
||||||
|
group = TASK_GROUP
|
||||||
|
description = "Build dynamic library in $profile mode for all targets"
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks["mergeUniversal${profileCapitalized}JniLibFolders"].dependsOn(buildTask)
|
||||||
|
|
||||||
|
for (targetPair in targetsList.withIndex()) {
|
||||||
|
val targetName = targetPair.value
|
||||||
|
val targetArch = archList[targetPair.index]
|
||||||
|
val targetArchCapitalized = targetArch.replaceFirstChar { it.uppercase() }
|
||||||
|
val targetBuildTask = project.tasks.register(
|
||||||
|
"rustBuild$targetArchCapitalized$profileCapitalized",
|
||||||
|
BuildTask::class.java
|
||||||
|
) {
|
||||||
|
group = TASK_GROUP
|
||||||
|
description = "Build dynamic library in $profile mode for $targetArch"
|
||||||
|
rootDirRel = config.rootDirRel
|
||||||
|
projectDir = project.projectDir.path
|
||||||
|
target = targetName
|
||||||
|
release = profile == "release"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTask.dependsOn(targetBuildTask)
|
||||||
|
tasks["merge$targetArchCapitalized${profileCapitalized}JniLibFolders"].dependsOn(
|
||||||
|
targetBuildTask
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src-tauri/gen/android/gradle.properties
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Project-wide Gradle settings.
|
||||||
|
# IDE (e.g. Android Studio) users:
|
||||||
|
# Gradle settings configured through the IDE *will override*
|
||||||
|
# any settings specified in this file.
|
||||||
|
# For more details on how to configure your build environment visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||||
|
org.gradle.configuration-cache=true
|
||||||
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
|
# org.gradle.parallel=true
|
||||||
|
# Kotlin code style for this project: "official" or "obsolete":
|
||||||
|
kotlin.code.style=official
|
||||||
|
|
||||||
|
# Our old plugin template had a bug that caused missing `consumer-rules.pro` files
|
||||||
|
# so we have to disable it for now.
|
||||||
|
# See https://github.com/tauri-apps/tauri/pull/15828#issuecomment-5199937796
|
||||||
|
android.proguard.failOnMissingFiles=false
|
||||||
|
|
||||||
|
# Keeping Gradle 9 compatible with current plugins
|
||||||
|
# TODO: Remove this in v3
|
||||||
|
android.builtInKotlin=false
|
||||||
|
android.newDsl=false
|
||||||
12
src-tauri/gen/android/gradle/gradle-daemon-jvm.properties
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#This file is generated by updateDaemonJvm
|
||||||
|
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/cf726b4a1c84b50457225f9bba6d7650/redirect
|
||||||
|
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/fa1e318c287360478e3c83a9a3ef1007/redirect
|
||||||
|
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/cf726b4a1c84b50457225f9bba6d7650/redirect
|
||||||
|
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/fa1e318c287360478e3c83a9a3ef1007/redirect
|
||||||
|
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/c2dd35c9d0aaf0ba6ad0791320f99dfc/redirect
|
||||||
|
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/e5810bd7fd1f8a586644409d395a7e55/redirect
|
||||||
|
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/cf726b4a1c84b50457225f9bba6d7650/redirect
|
||||||
|
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/fa1e318c287360478e3c83a9a3ef1007/redirect
|
||||||
|
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/7b3c4877c0749019e6805bb61e421497/redirect
|
||||||
|
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/d76df094a9cbbabd3b08251f9e61444a/redirect
|
||||||
|
toolchainVersion=25
|
||||||
BIN
src-tauri/gen/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
6
src-tauri/gen/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#Tue May 10 19:22:52 CST 2022
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
248
src-tauri/gen/android/gradlew
vendored
Executable file
|
|
@ -0,0 +1,248 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright © 2015 the original authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# gradlew start up script for POSIX generated by Gradle.
|
||||||
|
#
|
||||||
|
# Important for running:
|
||||||
|
#
|
||||||
|
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||||
|
# noncompliant, but you have some other compliant shell such as ksh or
|
||||||
|
# bash, then to run this script, type that shell name before the whole
|
||||||
|
# command line, like:
|
||||||
|
#
|
||||||
|
# ksh gradlew
|
||||||
|
#
|
||||||
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
|
# requires all of these POSIX shell features:
|
||||||
|
# * functions;
|
||||||
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
|
#
|
||||||
|
# Important for patching:
|
||||||
|
#
|
||||||
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
|
#
|
||||||
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
|
# space-separated string is a well documented source of bugs and security
|
||||||
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
|
# options in "$@", and eventually passing that to Java.
|
||||||
|
#
|
||||||
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
|
# see the in-line comments for details.
|
||||||
|
#
|
||||||
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
|
# Darwin, MinGW, and NonStop.
|
||||||
|
#
|
||||||
|
# (3) This script is generated from the Groovy template
|
||||||
|
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
|
# within the Gradle project.
|
||||||
|
#
|
||||||
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
app_path=$0
|
||||||
|
|
||||||
|
# Need this for daisy-chained symlinks.
|
||||||
|
while
|
||||||
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
|
[ -h "$app_path" ]
|
||||||
|
do
|
||||||
|
ls=$( ls -ld "$app_path" )
|
||||||
|
link=${ls#*' -> '}
|
||||||
|
case $link in #(
|
||||||
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# This is normally unused
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
APP_BASE_NAME=${0##*/}
|
||||||
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD=maximum
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
} >&2
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
} >&2
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "$( uname )" in #(
|
||||||
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
|
Darwin* ) darwin=true ;; #(
|
||||||
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
|
NONSTOP* ) nonstop=true ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
|
else
|
||||||
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD=java
|
||||||
|
if ! command -v java >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
|
case $MAX_FD in #(
|
||||||
|
max*)
|
||||||
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
|
warn "Could not query maximum file descriptor limit"
|
||||||
|
esac
|
||||||
|
case $MAX_FD in #(
|
||||||
|
'' | soft) :;; #(
|
||||||
|
*)
|
||||||
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
|
ulimit -n "$MAX_FD" ||
|
||||||
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
|
# * args from the command line
|
||||||
|
# * the main class name
|
||||||
|
# * -classpath
|
||||||
|
# * -D...appname settings
|
||||||
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
|
||||||
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Collect all arguments for the java command:
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
|
# and any embedded shellness will be escaped.
|
||||||
|
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||||
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Stop when "xargs" is not available.
|
||||||
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "xargs is not available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
||||||
82
src-tauri/gen/android/gradlew.bat
vendored
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
@rem SPDX-License-Identifier: Apache-2.0
|
||||||
|
@rem
|
||||||
|
|
||||||
|
@if "%DEBUG%"=="" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem gradlew startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables, and ensure extensions are enabled
|
||||||
|
setlocal EnableExtensions
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
|
echo. 1>&2
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
|
echo. 1>&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
|
"%COMSPEC%" /c exit 1
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
|
echo. 1>&2
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
|
echo. 1>&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
|
"%COMSPEC%" /c exit 1
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@rem Execute gradlew
|
||||||
|
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
|
||||||
|
@rem which allows us to clear the local environment before executing the java command
|
||||||
|
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
|
||||||
|
|
||||||
|
:exitWithErrorLevel
|
||||||
|
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
|
||||||
|
"%COMSPEC%" /c exit %ERRORLEVEL%
|
||||||
3
src-tauri/gen/android/settings.gradle
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
include ':app'
|
||||||
|
|
||||||
|
apply from: 'tauri.settings.gradle'
|
||||||
1
src-tauri/has-update.key.pub
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDNEQUVFQTk4QkE5REVFNjMKUldSajdwMjZtT3F1UGFzWUFIcjNNcjRUdnlGKzBzUGxTZ3BOTGFWcGRwN2pCd1JJTnRXbTE2d3EK
|
||||||
BIN
src-tauri/icons/128x128.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
src-tauri/icons/128x128@2x.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
BIN
src-tauri/icons/32x32.png
Normal file
|
After Width: | Height: | Size: 2 KiB |
BIN
src-tauri/icons/64x64.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
src-tauri/icons/Square107x107Logo.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src-tauri/icons/Square142x142Logo.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
src-tauri/icons/Square150x150Logo.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
src-tauri/icons/Square284x284Logo.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
src-tauri/icons/Square30x30Logo.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src-tauri/icons/Square310x310Logo.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
src-tauri/icons/Square44x44Logo.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src-tauri/icons/Square71x71Logo.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
src-tauri/icons/Square89x89Logo.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
src-tauri/icons/StoreLogo.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
|
</adaptive-icon>
|
||||||
BIN
src-tauri/icons/android/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
BIN
src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
src-tauri/icons/android/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 142 KiB |
BIN
src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="ic_launcher_background">#FFFFFF</color>
|
||||||
|
</resources>
|
||||||
BIN
src-tauri/icons/icon.icns
Normal file
BIN
src-tauri/icons/icon.ico
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
src-tauri/icons/icon.png
Normal file
|
After Width: | Height: | Size: 180 KiB |
BIN
src-tauri/icons/ios/AppIcon-20x20@1x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src-tauri/icons/ios/AppIcon-20x20@2x-1.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |