diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 64c2919b1..bf89a6280 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,53 +6,53 @@ on: merge_group: jobs: - ios-build: - runs-on: macos-latest - steps: - - uses: actions/checkout@v2 - with: - ref: dev - - uses: subosito/flutter-action@v2 - with: - # flutter-version: '2.5.2' - channel: 'stable' - - uses: actions/setup-python@v2 - with: - python-version: '3.8' - - name: Preprocess - run: | - # cd lib/server - # wget -q ${{ secrets.SECRET_SALT }} - # wget -q ${{ secrets.SECRET_WSALT }} - # cd ../.. - cat << EOF > lib/server/salt.dart - String getValid(foo) {return foo;} - EOF - cat << EOF > lib/server/wsalt.dart - String getValid(foo) {return foo;} - EOF - python3 preprocess-ios.py - - name: Podfile - run: | - cd ios - rm Podfile.lock - flutter clean - flutter pub get - pod install - pod update - cd .. - - name: Build - run: | - flutter build ios --release --no-codesign - mkdir -p Payload - mv ./build/ios/iphoneos/Runner.app Payload - zip -r -y Payload.zip Payload/Runner.app - mv Payload.zip Payload.ipa - - name: Upload IPA - uses: actions/upload-artifact@v2 - with: - name: ipa-build - path: Payload.ipa + # ios-build: + # runs-on: macos-latest + # steps: + # - uses: actions/checkout@v2 + # with: + # ref: dev + # - uses: subosito/flutter-action@v2 + # with: + # # flutter-version: '2.5.2' + # channel: 'stable' + # - uses: actions/setup-python@v2 + # with: + # python-version: '3.8' + # - name: Preprocess + # run: | + # # cd lib/server + # # wget -q ${{ secrets.SECRET_SALT }} + # # wget -q ${{ secrets.SECRET_WSALT }} + # # cd ../.. + # cat << EOF > lib/server/salt.dart + # String getValid(foo) {return foo;} + # EOF + # cat << EOF > lib/server/wsalt.dart + # String getValid(foo) {return foo;} + # EOF + # python3 preprocess-ios.py + # - name: Podfile + # run: | + # cd ios + # rm Podfile.lock + # flutter clean + # flutter pub get + # pod install + # pod update + # cd .. + # - name: Build + # run: | + # flutter build ios --release --no-codesign + # mkdir -p Payload + # mv ./build/ios/iphoneos/Runner.app Payload + # zip -r -y Payload.zip Payload/Runner.app + # mv Payload.zip Payload.ipa + # - name: Upload IPA + # uses: actions/upload-artifact@v2 + # with: + # name: ipa-build + # path: Payload.ipa # https://github.com/AppImageCrafters/appimage-builder-flutter-example/blob/main/.github/workflows/appimage.yml linux-build: @@ -69,6 +69,76 @@ jobs: run: | sudo apt-get update sudo apt-get install -y cmake ninja-build build-essential pkg-config curl file git unzip xz-utils zip libgtk-3-dev + - name: Clone project-violet/p7zip + run: git clone https://github.com/project-violet/p7zip.git + - run: mkdir -p p7zip/bin/ + - name: Build p7zip for linux/armhf + uses: pguyot/arm-runner-action@v2 + id: p7zip-armv7-linux-build + with: + base_image: raspios_lite:latest + copy_artifact_path: p7zip/bin/7zr + copy_artifact_dest: p7zip/bin/7zr + commands: | + cd p7zip + make 7zr + cd .. + - name: Copy bin + run: | + mkdir -p ./assets/p7zip/linux/armv7/ + sudo chmod 777 p7zip/bin/7zr + sudo chown $USER:$USER p7zip/bin/7zr + cp p7zip/bin/7zr ./assets/p7zip/linux/armv7/7zr + - name: Clean up project-violet/p7zip + run: | + cd p7zip + git add -A + git reset --hard HEAD + cd .. + - run: mkdir -p p7zip/bin/ + - name: Build p7zip for linux/arm64 + uses: pguyot/arm-runner-action@v2 + id: p7zip-arm64-linux-build + with: + base_image: raspios_lite_arm64:latest + copy_artifact_path: p7zip/bin/7zr + copy_artifact_dest: p7zip/bin/7zr + commands: | + cd p7zip + make 7zr + cd .. + - name: Copy bin + run: | + mkdir -p ./assets/p7zip/linux/armv8/ + sudo chmod 777 p7zip/bin/7zr + sudo chown $USER:$USER p7zip/bin/7zr + cp p7zip/bin/7zr ./assets/p7zip/linux/armv8/7zr + - name: Clean up project-violet/p7zip + run: | + cd p7zip + git add -A + git reset --hard HEAD + cd .. + - name: Build p7zip for linux/x86(not yet) + run: | + mkdir -p ./assets/p7zip/linux/x86/ + touch ./assets/p7zip/linux/x86/7zr + - name: Build p7zip for linux/x86_64 + run: | + cd p7zip + make 7zr + cd .. + - name: Copy bin + run: | + mkdir -p ./assets/p7zip/linux/x86_64/ + chmod 777 p7zip/bin/7zr + cp p7zip/bin/7zr ./assets/p7zip/linux/x86_64/7zr + - name: Clean up project-violet/p7zip + run: | + cd p7zip + git add -A + git reset --hard HEAD + cd .. - name: Build flutter app run: | # cd lib/server @@ -109,41 +179,41 @@ jobs: # files: './*.AppImage*' # repo_token: ${{ secrets.GITHUB_TOKEN }} - android-build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: dev - - uses: actions/setup-java@v1 - with: - java-version: '12.x' - - uses: subosito/flutter-action@v1 - with: - # flutter-version: '2.5.2' - channel: 'stable' - - uses: actions/setup-python@v2 - with: - python-version: '3.8' - - name: Preprocess - run: | - # cd lib/server - # wget -q ${{ secrets.SECRET_SALT }} - # wget -q ${{ secrets.SECRET_WSALT }} - # cd ../.. - cat << EOF > lib/server/salt.dart - String getValid(foo) {return foo;} - EOF - cat << EOF > lib/server/wsalt.dart - String getValid(foo) {return foo;} - EOF - python3 preprocess-android.py - - name: Build - run: | - flutter clean - flutter build apk --release - - name: Upload APK - uses: actions/upload-artifact@v2 - with: - name: apk-build - path: ./build/app/outputs/apk/release/app-release.apk + # android-build: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v2 + # with: + # ref: dev + # - uses: actions/setup-java@v1 + # with: + # java-version: '12.x' + # - uses: subosito/flutter-action@v1 + # with: + # # flutter-version: '2.5.2' + # channel: 'stable' + # - uses: actions/setup-python@v2 + # with: + # python-version: '3.8' + # - name: Preprocess + # run: | + # # cd lib/server + # # wget -q ${{ secrets.SECRET_SALT }} + # # wget -q ${{ secrets.SECRET_WSALT }} + # # cd ../.. + # cat << EOF > lib/server/salt.dart + # String getValid(foo) {return foo;} + # EOF + # cat << EOF > lib/server/wsalt.dart + # String getValid(foo) {return foo;} + # EOF + # python3 preprocess-android.py + # - name: Build + # run: | + # flutter clean + # flutter build apk --release + # - name: Upload APK + # uses: actions/upload-artifact@v2 + # with: + # name: apk-build + # path: ./build/app/outputs/apk/release/app-release.apk diff --git a/lib/checker/checker.dart b/lib/checker/checker.dart index f2758caab..e58140130 100644 --- a/lib/checker/checker.dart +++ b/lib/checker/checker.dart @@ -18,7 +18,7 @@ class VioletChecker { // // 0. get database path // - var dbPath = Platform.isAndroid + var dbPath = (Platform.isAndroid || Platform.isLinux) ? '${(await DefaultPathProvider.getBaseDirectory())}/data/data.db' : '${(await DefaultPathProvider.getBaseDirectory())}/data.db'; diff --git a/lib/database/database.dart b/lib/database/database.dart index 8fa98a377..19460cd30 100644 --- a/lib/database/database.dart +++ b/lib/database/database.dart @@ -34,7 +34,7 @@ class DataBaseManager { if (Platform.environment.containsKey('FLUTTER_TEST')) { dbPath = join(Directory.current.path, 'test/db/data.db'); } else { - dbPath = Platform.isAndroid + dbPath = (Platform.isAndroid || Platform.isLinux) ? '${(await DefaultPathProvider.getBaseDirectory())}/data/data.db' : '${(await DefaultPathProvider.getBaseDirectory())}/data.db'; } diff --git a/lib/pages/database_download/database_download_page.dart b/lib/pages/database_download/database_download_page.dart index 53c6d6020..717a7fe91 100644 --- a/lib/pages/database_download/database_download_page.dart +++ b/lib/pages/database_download/database_download_page.dart @@ -62,7 +62,7 @@ class DataBaseDownloadPageState extends State { try { final prefs = await MultiPreferences.getInstance(); if ((await prefs.getInt('db_exists')) == 1) { - var dbPath = Platform.isAndroid + var dbPath = (Platform.isAndroid || Platform.isLinux) ? '${(await DefaultPathProvider.getBaseDirectory())}/data/data.db' : '${(await DefaultPathProvider.getBaseDirectory())}/data.db'; if (await File(dbPath).exists()) await File(dbPath).delete(); @@ -104,9 +104,9 @@ class DataBaseDownloadPageState extends State { Future downloadFileLinux() async { try { - await downloadFileLinuxWith('latest', true); + await downloadFileAndroidWith('latest', true); } catch(e){ - await downloadFileLinuxWith('old', false); + await downloadFileAndroidWith('old', false); } } diff --git a/lib/pages/database_download/decompress.dart b/lib/pages/database_download/decompress.dart index 6c710519d..98895cd5f 100644 --- a/lib/pages/database_download/decompress.dart +++ b/lib/pages/database_download/decompress.dart @@ -1,6 +1,7 @@ // This source code is a part of Project Violet. // Copyright (C) 2020-2023. violet-team. Licensed under the Apache-2.0 License. +import 'dart:convert'; import 'dart:ffi'; import 'dart:io'; import 'dart:isolate'; @@ -9,6 +10,8 @@ import 'package:device_info_plus/device_info_plus.dart'; import 'package:ffi/ffi.dart'; import 'package:flutter/services.dart'; import 'package:path_provider/path_provider.dart'; +import 'package:violet/log/log.dart'; +import 'package:violet/settings/path.dart'; typedef _NativeP7zipShell = NativeFunction)>; typedef _DartP7zipShell = int Function(Pointer); @@ -49,7 +52,37 @@ class P7zip { final soPath = await _checkSharedLibrary(); print(soPath); if (soPath == null) { - return null; + final binPath = await _checkBinary(); + if(binPath == null){ + return null; + } + final filesStr = files.join(' '); + await ((()async{ + Process process = await Process.start( + "chmod", + [ + "+x", + "${(await DefaultPathProvider.getBaseDirectory())}/7zr", + ], + ); + await process.stdout + .transform(utf8.decoder) + .forEach(print); + })()); + await ((()async{ + Process process = await Process.start( + "${(await DefaultPathProvider.getBaseDirectory())}/7zr", + [ + "e","$filesStr", + "-o$path" + ], + ); + await process.stdout + .transform(utf8.decoder) + .forEach(print); + })()); + // return null; + return path; } final filesStr = files.join(' '); @@ -97,4 +130,49 @@ class P7zip { return libraryFile.path; } + Future _checkBinary() async { + if(!Platform.isLinux){ + return null; + } + + var _arch = await ((()async{ + var _a = ''; + // https://stackoverflow.com/questions/70247458/flutter-dart-print-output-of-all-child-processes-to-stdout + Process process = await Process.start( + "uname", + [ + "-m" + ], + ); + + await process.stdout + .transform(utf8.decoder) + .forEach((value){ + if(_a.isEmpty){ + _a = value.replaceAll('\r', '').replaceAll('\n', ''); + } + }); + if((_a.contains('arm') || _a.contains('aarch')) && (_a.contains('32') || _a.contains('v7'))) return 'armv7'; + if((_a.contains('arm') || _a.contains('aarch')) && (_a.contains('64') || _a.contains('v8'))) return 'armv8'; + if(_a == 'x86_64' || _a == 'amd64') return 'x86_64'; + if((_a.contains('i') || _a.contains('x')) && _a.contains('86') && !_a.contains('64')) return 'x86'; + })()); + final binaryPath = 'assets/p7zip/linux/$_arch/7zr'; + final binaryContent = await rootBundle.load(binaryPath); + final tempDir = await DefaultPathProvider.getBaseDirectory(); + final binaryFile = File('${tempDir}/7zr'); + if(await binaryFile.exists()){ + await binaryFile.delete(); + } + if(await Directory('${tempDir}/').exists()){ + Logger.info('${tempDir}/ exists'); + } + final createdFile = await binaryFile.create(); + final openFile = await createdFile.open(mode: FileMode.write); + final writtenFile = + await openFile.writeFrom(Uint8List.view(binaryContent.buffer)); + await writtenFile.close(); + + return binaryFile.path; + } } diff --git a/pubspec.yaml b/pubspec.yaml index d8f08ea8d..f699d4922 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -182,6 +182,11 @@ flutter: - assets/p7zip/x86/lib7zr.so # @dependent: android - assets/p7zip/x86_64/lib7zr.so # @dependent: android + - assets/p7zip/linux/armv7/7zr # @dependent: linux + - assets/p7zip/linux/armv8/7zr # @dependent: linux + - assets/p7zip/linux/x86/7zr # @dependent: linux + - assets/p7zip/linux/x86_64/7zr # @dependent: linux + - assets/webview/ - assets/db/