mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-14 04:13:43 +00:00
Compare commits
40
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab371d21f9 | ||
|
|
4fc67a676e | ||
|
|
864e6b0477 | ||
|
|
0b1d6ca1f6 | ||
|
|
c2049806a5 | ||
|
|
a58738f910 | ||
|
|
606f93e885 | ||
|
|
509e5c9f5e | ||
|
|
fb38253045 | ||
|
|
782205ef27 | ||
|
|
a372b67edb | ||
|
|
2d86b5c132 | ||
|
|
63b3144633 | ||
|
|
1b0178fed9 | ||
|
|
83febe0a00 | ||
|
|
987580d400 | ||
|
|
0919936050 | ||
|
|
acc7ed8f6b | ||
|
|
ccb3267fba | ||
|
|
1249493a8a | ||
|
|
107141bbe7 | ||
|
|
b329fee107 | ||
|
|
3ce95f21fd | ||
|
|
f54ed5df5a | ||
|
|
727b7edb84 | ||
|
|
f5891ee03d | ||
|
|
724276ac69 | ||
|
|
a3f559c8e5 | ||
|
|
edd189a8a8 | ||
|
|
c970378fd7 | ||
|
|
8b61343aef | ||
|
|
2cb93a03e2 | ||
|
|
81dfc073a6 | ||
|
|
427921ccab | ||
|
|
f4876c8a0e | ||
|
|
35a3625b11 | ||
|
|
dc9b501e35 | ||
|
|
85fe92a378 | ||
|
|
983d9ad09e | ||
|
|
d9f757aaf0 |
No files matched your search
+103
-26
@@ -1,42 +1,119 @@
|
||||
name-template: 'v$NEXT_PATCH_VERSION 🌈'
|
||||
tag-template: 'v$NEXT_PATCH_VERSION'
|
||||
name-template: "v$NEXT_PATCH_VERSION 🌈"
|
||||
tag-template: "v$NEXT_PATCH_VERSION"
|
||||
categories:
|
||||
- title: '🆕 Features'
|
||||
- title: "🆕 Features"
|
||||
labels:
|
||||
- 'feat'
|
||||
- 'feature'
|
||||
- 'enhancement'
|
||||
- title: '🐛 Bug Fixes'
|
||||
- "feat"
|
||||
- "feature"
|
||||
- "enhancement"
|
||||
- title: "🐛 Bug Fixes"
|
||||
labels:
|
||||
- 'fix'
|
||||
- 'bugfix'
|
||||
- 'bug'
|
||||
- title: '🔧 Performance Improvements'
|
||||
- "fix"
|
||||
- "bugfix"
|
||||
- "bug"
|
||||
- title: "🔧 Performance Improvements"
|
||||
labels:
|
||||
- 'perf'
|
||||
- title: '🧪 Tests'
|
||||
label: 'test'
|
||||
- title: '🧰 Maintenance'
|
||||
label: 'chore'
|
||||
- title: '📖 Document'
|
||||
label: 'docs'
|
||||
- title: '🚀 CI/CD'
|
||||
label: 'ci'
|
||||
- title: '🌎 Internationalization'
|
||||
label: 'translation'
|
||||
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
|
||||
- "perf"
|
||||
- title: "🧪 Tests"
|
||||
label: "test"
|
||||
- title: "🧰 Maintenance"
|
||||
label: "chore"
|
||||
- title: "📖 Document"
|
||||
label: "docs"
|
||||
- title: "🚀 CI/CD"
|
||||
label: "ci"
|
||||
- title: "🌎 Internationalization"
|
||||
label: "translation"
|
||||
change-template: "- $TITLE @$AUTHOR (#$NUMBER)"
|
||||
version-resolver:
|
||||
major:
|
||||
labels:
|
||||
- 'major'
|
||||
- "major"
|
||||
minor:
|
||||
labels:
|
||||
- 'minor'
|
||||
- "minor"
|
||||
patch:
|
||||
labels:
|
||||
- 'patch'
|
||||
- "patch"
|
||||
default: patch
|
||||
template: |
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Windows</th>
|
||||
<th>MacOS</th>
|
||||
<th colspan="4">Linux</th>
|
||||
<th>Android</th>
|
||||
<th>iOS</th>
|
||||
<th>Docker</th>
|
||||
<th colspan="2">Qnap</th>
|
||||
<th colspan="8">Web</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>EXE</code></td>
|
||||
<td><code>Portable</code></td>
|
||||
<td><code>DMG</code></td>
|
||||
<td><code>Flathub</code></td>
|
||||
<td><code>SNAP</code></td>
|
||||
<td><code>DEB</code></td>
|
||||
<td><code>AppImage</code></td>
|
||||
<td><code>APK</code></td>
|
||||
<td><code>IPA</code></td>
|
||||
<td>-</td>
|
||||
<td colspan="2"><code>QPKG</code></td>
|
||||
<td colspan="3"><code>Windows</code></td>
|
||||
<td colspan="2"><code>MacOS</code></td>
|
||||
<td colspan="3"><code>Linux</code></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>-</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>amd64</td>
|
||||
<td>arm64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>386</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>386</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64-portable.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-macos.dmg">Link</a></td>
|
||||
<td><a href="https://flathub.org/apps/com.gopeed.Gopeed">Link</a></td>
|
||||
<td><a href="https://snapcraft.io/gopeed">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-amd64.deb">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-x86_64.AppImage">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-android.apk">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-ios.ipa">Link</a></td>
|
||||
<td><a href="https://hub.docker.com/r/liwei2633/gopeed">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-$version-qnap-amd64.qpkg">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-$version-qnap-arm64.qpkg">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-amd64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-arm64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-386.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-macos-amd64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-macos-arm64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-amd64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-arm64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-386.zip">Link</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
# Release notes
|
||||
|
||||
$CHANGES
|
||||
|
||||
+112
-13
@@ -14,7 +14,7 @@ on:
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.23"
|
||||
FLUTTER_VERSION: "3.24.3"
|
||||
FLUTTER_VERSION: "3.24.5"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -52,6 +52,7 @@ jobs:
|
||||
mv ChineseSimplified.isl "C:\Program Files (x86)\Inno Setup 6\Languages\"
|
||||
|
||||
go build -tags nosqlite -ldflags="-w -s -X github.com/GopeedLab/gopeed/pkg/base.Version=$env:VERSION" -buildmode=c-shared -o ui/flutter/windows/libgopeed.dll github.com/GopeedLab/gopeed/bind/desktop
|
||||
go build -ldflags="-w -s" -o ui/flutter/assets/host/host.exe github.com/GopeedLab/gopeed/cmd/host
|
||||
cd ui/flutter
|
||||
$TAG = "v$env:VERSION"
|
||||
flutter build windows
|
||||
@@ -97,11 +98,13 @@ jobs:
|
||||
PrivilegesRequired=lowest
|
||||
OutputBaseFilename=gopeed
|
||||
SetupIconFile=..\..\assets\icon\icon.ico
|
||||
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||
Compression=lzma
|
||||
SolidCompression=yes
|
||||
WizardStyle=modern
|
||||
LanguageDetectionMethod=uilanguage
|
||||
ShowLanguageDialog=yes
|
||||
CloseApplications=force
|
||||
|
||||
[Languages]
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
@@ -111,7 +114,7 @@ jobs:
|
||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||
|
||||
[Files]
|
||||
Source: ".\x64\runner\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
|
||||
Source: ".\x64\runner\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs;
|
||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||
|
||||
[UninstallDelete]
|
||||
@@ -148,10 +151,13 @@ jobs:
|
||||
VERSION: ${{ needs.get-release.outputs.version }}
|
||||
run: |
|
||||
go build -tags nosqlite -ldflags="-w -s -X github.com/GopeedLab/gopeed/pkg/base.Version=$VERSION" -buildmode=c-shared -o libgopeed.dylib github.com/GopeedLab/gopeed/bind/desktop
|
||||
- uses: actions/upload-artifact@v3
|
||||
go build -ldflags="-w -s" github.com/GopeedLab/gopeed/cmd/host
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: macos-arm64-lib
|
||||
path: libgopeed.dylib
|
||||
path: |
|
||||
libgopeed.dylib
|
||||
host
|
||||
build-macos:
|
||||
if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'macos' }}
|
||||
runs-on: macos-13
|
||||
@@ -183,12 +189,18 @@ jobs:
|
||||
|
||||
# amd64 lib
|
||||
go build -tags nosqlite -ldflags="-w -s -X github.com/GopeedLab/gopeed/pkg/base.Version=$VERSION" -buildmode=c-shared -o ui/flutter/lib-amd64/libgopeed.dylib github.com/GopeedLab/gopeed/bind/desktop
|
||||
go build -ldflags="-w -s" -o ui/flutter/lib-amd64/host github.com/GopeedLab/gopeed/cmd/host
|
||||
# universal binary
|
||||
mkdir -p ui/flutter/macos/Frameworks
|
||||
cp ui/flutter/lib-amd64/libgopeed.dylib ui/flutter/macos/Frameworks/amd64-lib
|
||||
cp ui/flutter/lib-arm64/libgopeed.dylib ui/flutter/macos/Frameworks/arm64-lib
|
||||
cp ui/flutter/lib-amd64/host ui/flutter/macos/Frameworks/amd64-host
|
||||
cp ui/flutter/lib-arm64/host ui/flutter/macos/Frameworks/arm64-host
|
||||
cd ui/flutter/macos/Frameworks
|
||||
lipo -create -output libgopeed.dylib amd64-lib arm64-lib
|
||||
lipo -create -output host amd64-host arm64-host
|
||||
rm -rf amd64-lib arm64-lib amd64-host arm64-host
|
||||
mv host ../../assets/host/host
|
||||
|
||||
cd $PROJECT_DIR/ui/flutter
|
||||
flutter build macos
|
||||
@@ -213,7 +225,7 @@ jobs:
|
||||
overwrite: true
|
||||
build-linux:
|
||||
if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'linux' }}
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
needs: [get-release]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -237,6 +249,7 @@ jobs:
|
||||
VERSION: ${{ needs.get-release.outputs.version }}
|
||||
run: |
|
||||
go build -tags nosqlite -ldflags="-w -s -X github.com/GopeedLab/gopeed/pkg/base.Version=$VERSION" -buildmode=c-shared -o ui/flutter/linux/bundle/lib/libgopeed.so github.com/GopeedLab/gopeed/bind/desktop
|
||||
go build -ldflags="-w -s" -o ui/flutter/assets/host/host github.com/GopeedLab/gopeed/cmd/host
|
||||
cd ui/flutter
|
||||
dart pub global activate -sgit https://github.com/GopeedLab/flutter_distributor.git --git-path packages/flutter_distributor
|
||||
flutter_distributor package --platform linux --targets appimage,deb
|
||||
@@ -267,6 +280,7 @@ jobs:
|
||||
VERSION: ${{ needs.get-release.outputs.version }}
|
||||
run: |
|
||||
go build -tags nosqlite -ldflags="-w -s -X github.com/GopeedLab/gopeed/pkg/base.Version=$VERSION" -buildmode=c-shared -o ui/flutter/linux/bundle/lib/libgopeed.so github.com/GopeedLab/gopeed/bind/desktop
|
||||
go build -ldflags="-w -s" -o ui/flutter/assets/host/host github.com/GopeedLab/gopeed/cmd/host
|
||||
cd ui/flutter
|
||||
|
||||
sudo snap install snapcraft --classic
|
||||
@@ -280,11 +294,12 @@ jobs:
|
||||
description: High speed downloader that supports all platforms.
|
||||
|
||||
confinement: strict
|
||||
base: core22
|
||||
base: core24
|
||||
grade: stable
|
||||
|
||||
architectures:
|
||||
- build-on: amd64
|
||||
platforms:
|
||||
amd64:
|
||||
build-on: amd64
|
||||
build-for: amd64
|
||||
|
||||
slots:
|
||||
@@ -295,13 +310,14 @@ jobs:
|
||||
|
||||
apps:
|
||||
gopeed:
|
||||
command-chain:
|
||||
- bin/gpu-2404-wrapper
|
||||
command: bin/gopeed
|
||||
extensions: [gnome]
|
||||
common-id: com.gopeed.Gopeed
|
||||
plugs:
|
||||
- network
|
||||
- home
|
||||
slots:
|
||||
- dbus-gopeed
|
||||
parts:
|
||||
flutter-git:
|
||||
source: https://github.com/flutter/flutter.git
|
||||
@@ -344,6 +360,29 @@ jobs:
|
||||
flutter build linux --release -v
|
||||
mkdir -p \$CRAFT_PART_INSTALL/bin/
|
||||
cp -r build/linux/*/release/bundle/* \$CRAFT_PART_INSTALL/bin/
|
||||
gpu-2404:
|
||||
after: [gopeed]
|
||||
source: https://github.com/canonical/gpu-snap.git
|
||||
plugin: dump
|
||||
override-prime: |
|
||||
craftctl default
|
||||
\${CRAFT_PART_SRC}/bin/gpu-2404-cleanup mesa-2404
|
||||
prime:
|
||||
- bin/gpu-2404-wrapper
|
||||
|
||||
plugs:
|
||||
gpu-2404:
|
||||
interface: content
|
||||
target: \$SNAP/gpu-2404
|
||||
default-provider: mesa-2404
|
||||
|
||||
layout:
|
||||
/usr/share/libdrm:
|
||||
bind: \$SNAP/gpu-2404/libdrm
|
||||
/usr/share/drirc.d:
|
||||
symlink: \$SNAP/gpu-2404/drirc.d
|
||||
/usr/share/X11/XErrorDB:
|
||||
symlink: \$SNAP/gpu-2404/X11/XErrorDB
|
||||
EOF
|
||||
|
||||
cp linux/assets/com.gopeed.Gopeed.desktop snap/gui/gopeed.desktop
|
||||
@@ -426,7 +465,7 @@ jobs:
|
||||
asset_path: ui/flutter/dist/*
|
||||
overwrite: true
|
||||
build-web:
|
||||
if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'web' }}
|
||||
if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'web' || github.event.inputs.platform == 'qnap' }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: [get-release]
|
||||
steps:
|
||||
@@ -441,8 +480,9 @@ jobs:
|
||||
env:
|
||||
VERSION: ${{ needs.get-release.outputs.version }}
|
||||
run: |
|
||||
VERSION=${VERSION:-$(date +%y%m%d%H%M)} # Use current time as version if not specified
|
||||
cd ui/flutter
|
||||
flutter build web --web-renderer html
|
||||
flutter build web --no-web-resources-cdn
|
||||
cd ../../
|
||||
cp -r ui/flutter/build/web cmd/web/dist
|
||||
mkdir -p dist/zip
|
||||
@@ -468,12 +508,71 @@ jobs:
|
||||
|| true
|
||||
done
|
||||
done
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: web-dist
|
||||
path: dist/zip/
|
||||
- name: Upload
|
||||
uses: shogo82148/actions-upload-release-asset@v1
|
||||
with:
|
||||
upload_url: ${{ needs.get-release.outputs.upload_url }}
|
||||
asset_path: dist/zip/*
|
||||
overwrite: true
|
||||
build-qnap:
|
||||
if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'qnap' }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: [get-release, build-web]
|
||||
steps:
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.8.18"
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: web-dist
|
||||
path: dist/zip/
|
||||
- name: Build
|
||||
env:
|
||||
VERSION: ${{ needs.get-release.outputs.version }}
|
||||
run: |
|
||||
sudo apt update -y
|
||||
sudo apt install -y pv bsdmainutils
|
||||
wget -O qdk2_0.32.bionic_amd64.deb "https://github.com/qnap-dev/qdk2/releases/download/v0.32/qdk2_0.32.bionic_amd64.deb"
|
||||
dpkg -X qdk2_0.32.bionic_amd64.deb qdk2 # Direct installs will fail due to missing dependencies!
|
||||
[[ -d qdk2 ]] || exit 1
|
||||
|
||||
export PATH=$(pwd)/qdk2/usr/bin:$(pwd)/qdk2/usr/share/qdk2/QDK/bin:${PATH}
|
||||
wget -O Gopeed.template.tar.gz "https://github.com/GopeedLab/QpkgBuild/raw/refs/heads/master/template/Gopeed.template.tar.gz"
|
||||
tar -zxf Gopeed.template.tar.gz
|
||||
[[ -d Gopeed ]] || exit 1
|
||||
|
||||
goos=linux
|
||||
goarch_arr=(amd64 arm64)
|
||||
for goarch in "${goarch_arr[@]}"; do
|
||||
qarch=x86_64
|
||||
[[ "${goarch}" == "arm64" ]] && qarch=arm_64
|
||||
name=gopeed-web-v${VERSION}-${goos}-${goarch}
|
||||
unzip dist/zip/${name}.zip -d dist/${name}
|
||||
cp dist/${name}/${name}/* Gopeed/${qarch}/
|
||||
done
|
||||
cd Gopeed
|
||||
sed -i -e 's/__QPKG_VER__/${VERSION}/g' qpkg.cfg
|
||||
qbuild || exit 1
|
||||
|
||||
mkdir -p ../dist/qnap
|
||||
goos=qnap
|
||||
for goarch in "${goarch_arr[@]}"; do
|
||||
qarch=x86_64
|
||||
[[ "${goarch}" == "arm64" ]] && qarch=arm_64
|
||||
sname=Gopeed_${VERSION}_${qarch}.qpkg
|
||||
dname=gopeed-v${VERSION}-${goos}-${goarch}.qpkg
|
||||
[[ -f build/${sname} ]] && cp -ra build/${sname} ../dist/qnap/${dname}
|
||||
done
|
||||
- name: Upload
|
||||
uses: shogo82148/actions-upload-release-asset@v1
|
||||
with:
|
||||
upload_url: ${{ needs.get-release.outputs.upload_url }}
|
||||
asset_path: dist/qnap/*
|
||||
overwrite: true
|
||||
build-docker:
|
||||
if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'docker' }}
|
||||
runs-on: ubuntu-latest
|
||||
@@ -499,7 +598,7 @@ jobs:
|
||||
- name: Build flutter web
|
||||
run: |
|
||||
cd ui/flutter
|
||||
flutter build web --web-renderer html
|
||||
flutter build web --no-web-resources-cdn
|
||||
cd ../../
|
||||
rm -rf cmd/web/dist
|
||||
cp -r ui/flutter/build/web cmd/web/dist
|
||||
|
||||
@@ -28,7 +28,7 @@ on:
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.23"
|
||||
FLUTTER_VERSION: "3.24.3"
|
||||
FLUTTER_VERSION: "3.24.5"
|
||||
|
||||
jobs:
|
||||
# lint:
|
||||
@@ -63,7 +63,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ windows-latest, macos-latest, ubuntu-latest ]
|
||||
os: [ windows-latest, macos-latest, ubuntu-22.04 ]
|
||||
needs: [ test ]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -73,17 +73,17 @@ jobs:
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
- if: runner.os == 'windows-latest'
|
||||
- if: runner.os == 'Windows'
|
||||
run: |
|
||||
go build -tags nosqlite -ldflags="-w -s" -buildmode=c-shared -o ui/flutter/windows/libgopeed.dll github.com/GopeedLab/gopeed/bind/desktop
|
||||
cd ui/flutter
|
||||
flutter build windows
|
||||
- if: runner.os == 'macos-latest'
|
||||
- if: runner.os == 'macOS'
|
||||
run: |
|
||||
go build -tags nosqlite -ldflags="-w -s" -buildmode=c-shared -o ui/flutter/macos/Frameworks/libgopeed.dylib github.com/GopeedLab/gopeed/bind/desktop
|
||||
cd ui/flutter
|
||||
flutter build macos
|
||||
- if: runner.os == 'ubuntu-latest'
|
||||
- if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y ninja-build libgtk-3-dev libayatana-appindicator3-dev
|
||||
@@ -140,7 +140,7 @@ jobs:
|
||||
- name: Build
|
||||
run: |
|
||||
cd ui/flutter
|
||||
flutter build web --web-renderer html
|
||||
flutter build web --no-web-resources-cdn
|
||||
cd ../../
|
||||
rm -rf cmd/web/dist
|
||||
cp -r ui/flutter/build/web cmd/web/dist
|
||||
@@ -160,7 +160,7 @@ jobs:
|
||||
- name: Build
|
||||
run: |
|
||||
cd ui/flutter
|
||||
flutter build web --web-renderer html
|
||||
flutter build web --no-web-resources-cdn
|
||||
cd ../../
|
||||
rm -rf cmd/web/dist
|
||||
cp -r ui/flutter/build/web cmd/web/dist
|
||||
|
||||
+2
-3
@@ -8,14 +8,13 @@ RUN CGO_ENABLED=0 go build -tags nosqlite,web \
|
||||
-ldflags="-s -w -X github.com/GopeedLab/gopeed/pkg/base.Version=$VERSION -X github.com/GopeedLab/gopeed/pkg/base.InDocker=true" \
|
||||
-o dist/gopeed github.com/GopeedLab/gopeed/cmd/web
|
||||
|
||||
FROM alpine:3.14.2
|
||||
FROM alpine:3.18
|
||||
LABEL maintainer="monkeyWie"
|
||||
WORKDIR /app
|
||||
COPY --from=go /app/dist/gopeed ./
|
||||
COPY entrypoint.sh ./entrypoint.sh
|
||||
RUN apk update && \
|
||||
apk upgrade --no-cache && \
|
||||
apk add --no-cache bash su-exec; \
|
||||
apk add --no-cache su-exec ; \
|
||||
chmod +x ./entrypoint.sh && \
|
||||
rm -rf /var/cache/apk/*
|
||||
VOLUME ["/app/storage"]
|
||||
|
||||
@@ -22,66 +22,80 @@ Visit ✈ [Official Website](https://gopeed.com) | 📖 [Official Docs](https://
|
||||
## Download
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Platform</th>
|
||||
<th>Package Type</th>
|
||||
<th>Download Link</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan=2>Windows</td>
|
||||
<td><code>EXE Installer</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64.zip">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Portable ZIP</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64-portable.zip">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MacOS</td>
|
||||
<td><code>DMG Installer</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-macos.dmg">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan=4>Linux</td>
|
||||
<td><code>Flathub</code></td>
|
||||
<td><a href="https://flathub.org/apps/com.gopeed.Gopeed">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SNAP</code></td>
|
||||
<td><a href="https://snapcraft.io/gopeed">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>DEB</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-amd64.deb">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>AppImage</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-x86_64.AppImage">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Android</td>
|
||||
<td><code>APK</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-android.apk">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>iOS</td>
|
||||
<td><code>IPA</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-ios.ipa">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Web</td>
|
||||
<td></td>
|
||||
<td><a href="https://github.com/GopeedLab/gopeed/releases/latest">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Docker</td>
|
||||
<td></td>
|
||||
<td><a href="https://hub.docker.com/r/liwei2633/gopeed">Link</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Windows</th>
|
||||
<th>MacOS</th>
|
||||
<th colspan="4">Linux</th>
|
||||
<th>Android</th>
|
||||
<th>iOS</th>
|
||||
<th>Docker</th>
|
||||
<th colspan="2">Qnap</th>
|
||||
<th colspan="8">Web</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>EXE</code></td>
|
||||
<td><code>Portable</code></td>
|
||||
<td><code>DMG</code></td>
|
||||
<td><code>Flathub</code></td>
|
||||
<td><code>SNAP</code></td>
|
||||
<td><code>DEB</code></td>
|
||||
<td><code>AppImage</code></td>
|
||||
<td><code>APK</code></td>
|
||||
<td><code>IPA</code></td>
|
||||
<td>-</td>
|
||||
<td colspan="2"><code>QPKG</code></td>
|
||||
<td colspan="3"><code>Windows</code></td>
|
||||
<td colspan="2"><code>MacOS</code></td>
|
||||
<td colspan="3"><code>Linux</code></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>-</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>amd64</td>
|
||||
<td>arm64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>386</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>386</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64-portable.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-macos.dmg">Link</a></td>
|
||||
<td><a href="https://flathub.org/apps/com.gopeed.Gopeed">Link</a></td>
|
||||
<td><a href="https://snapcraft.io/gopeed">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-amd64.deb">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-x86_64.AppImage">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-android.apk">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-ios.ipa">Link</a></td>
|
||||
<td><a href="https://hub.docker.com/r/liwei2633/gopeed">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-$version-qnap-amd64.qpkg">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-$version-qnap-arm64.qpkg">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-amd64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-arm64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-386.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-macos-amd64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-macos-arm64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-amd64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-arm64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-386.zip">Link</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
More about installation, please refer to [Installation](https://docs.gopeed.com/install.html)
|
||||
@@ -174,7 +188,7 @@ command:
|
||||
- android
|
||||
|
||||
```bash
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s -checklinkname=0" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
cd ui/flutter
|
||||
flutter build apk
|
||||
```
|
||||
|
||||
+75
-61
@@ -22,66 +22,80 @@ Gopeed (正式名 Go Speed) は `Golang` + `Flutter` によって開発された
|
||||
## インストール
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Platform</th>
|
||||
<th>Package Type</th>
|
||||
<th>Download Link</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan=2>Windows</td>
|
||||
<td><code>EXE Installer</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64.zip">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Portable ZIP</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64-portable.zip">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MacOS</td>
|
||||
<td><code>DMG Installer</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-macos.dmg">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan=4>Linux</td>
|
||||
<td><code>Flathub</code></td>
|
||||
<td><a href="https://flathub.org/apps/com.gopeed.Gopeed">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SNAP</code></td>
|
||||
<td><a href="https://snapcraft.io/gopeed">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>DEB</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-amd64.deb">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>AppImage</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-x86_64.AppImage">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Android</td>
|
||||
<td><code>APK</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-android.apk">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>iOS</td>
|
||||
<td><code>IPA</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-ios.ipa">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Web</td>
|
||||
<td></td>
|
||||
<td><a href="https://github.com/GopeedLab/gopeed/releases/latest">Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Docker</td>
|
||||
<td></td>
|
||||
<td><a href="https://hub.docker.com/r/liwei2633/gopeed">Link</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Windows</th>
|
||||
<th>MacOS</th>
|
||||
<th colspan="4">Linux</th>
|
||||
<th>Android</th>
|
||||
<th>iOS</th>
|
||||
<th>Docker</th>
|
||||
<th colspan="2">Qnap</th>
|
||||
<th colspan="8">Web</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>EXE</code></td>
|
||||
<td><code>Portable</code></td>
|
||||
<td><code>DMG</code></td>
|
||||
<td><code>Flathub</code></td>
|
||||
<td><code>SNAP</code></td>
|
||||
<td><code>DEB</code></td>
|
||||
<td><code>AppImage</code></td>
|
||||
<td><code>APK</code></td>
|
||||
<td><code>IPA</code></td>
|
||||
<td>-</td>
|
||||
<td colspan="2"><code>QPKG</code></td>
|
||||
<td colspan="3"><code>Windows</code></td>
|
||||
<td colspan="2"><code>MacOS</code></td>
|
||||
<td colspan="3"><code>Linux</code></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>-</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>amd64</td>
|
||||
<td>arm64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>386</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>386</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64-portable.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-macos.dmg">Link</a></td>
|
||||
<td><a href="https://flathub.org/apps/com.gopeed.Gopeed">Link</a></td>
|
||||
<td><a href="https://snapcraft.io/gopeed">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-amd64.deb">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-x86_64.AppImage">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-android.apk">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-ios.ipa">Link</a></td>
|
||||
<td><a href="https://hub.docker.com/r/liwei2633/gopeed">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-$version-qnap-amd64.qpkg">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-$version-qnap-arm64.qpkg">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-amd64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-arm64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-386.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-macos-amd64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-macos-arm64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-amd64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-arm64.zip">Link</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-386.zip">Link</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
インストールについての詳細は、[インストール](https://docs.gopeed.com/install.html)を参照してください。
|
||||
@@ -162,7 +176,7 @@ gomobile init
|
||||
- android
|
||||
|
||||
```bash
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s -checklinkname=0" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
cd ui/flutter
|
||||
flutter build apk
|
||||
```
|
||||
|
||||
+75
-61
@@ -22,66 +22,80 @@ Truy cập ✈ [Trang web chính thức](https://gopeed.com) | 📖 [Tài liệu
|
||||
## Tải về
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nền tảng</th>
|
||||
<th>Loại gói</th>
|
||||
<th>Liên kết tải xuống</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan=2>Windows</td>
|
||||
<td><code>Bộ cài đặt EXE</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64.zip">Liên kết</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>ZIP Portable</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64-portable.zip">Liên kết</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MacOS</td>
|
||||
<td><code>Bộ cài đặt DMG</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-macos.dmg">Liên kết</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan=4>Linux</td>
|
||||
<td><code>Flathub</code></td>
|
||||
<td><a href="https://flathub.org/apps/com.gopeed.Gopeed">Liên kết</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SNAP</code></td>
|
||||
<td><a href="https://snapcraft.io/gopeed">Liên kết</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>DEB</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-amd64.deb">Liên kết</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>AppImage</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-x86_64.AppImage">Liên kết</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Android</td>
|
||||
<td><code>APK</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-android.apk">Liên kết</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>iOS</td>
|
||||
<td><code>IPA</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-ios.ipa">Liên kết</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Web</td>
|
||||
<td></td>
|
||||
<td><a href="https://github.com/GopeedLab/gopeed/releases/latest">Liên kết</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Docker</td>
|
||||
<td></td>
|
||||
<td><a href="https://hub.docker.com/r/liwei2633/gopeed">Liên kết</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Windows</th>
|
||||
<th>MacOS</th>
|
||||
<th colspan="4">Linux</th>
|
||||
<th>Android</th>
|
||||
<th>iOS</th>
|
||||
<th>Docker</th>
|
||||
<th colspan="2">Qnap</th>
|
||||
<th colspan="8">Web</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>EXE</code></td>
|
||||
<td><code>Portable</code></td>
|
||||
<td><code>DMG</code></td>
|
||||
<td><code>Flathub</code></td>
|
||||
<td><code>SNAP</code></td>
|
||||
<td><code>DEB</code></td>
|
||||
<td><code>AppImage</code></td>
|
||||
<td><code>APK</code></td>
|
||||
<td><code>IPA</code></td>
|
||||
<td>-</td>
|
||||
<td colspan="2"><code>QPKG</code></td>
|
||||
<td colspan="3"><code>Windows</code></td>
|
||||
<td colspan="2"><code>MacOS</code></td>
|
||||
<td colspan="3"><code>Linux</code></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>-</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>amd64</td>
|
||||
<td>arm64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>386</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>386</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64.zip">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64-portable.zip">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-macos.dmg">Liên kết</a></td>
|
||||
<td><a href="https://flathub.org/apps/com.gopeed.Gopeed">Liên kết</a></td>
|
||||
<td><a href="https://snapcraft.io/gopeed">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-amd64.deb">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-x86_64.AppImage">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-android.apk">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-ios.ipa">Liên kết</a></td>
|
||||
<td><a href="https://hub.docker.com/r/liwei2633/gopeed">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-$version-qnap-amd64.qpkg">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-$version-qnap-arm64.qpkg">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-amd64.zip">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-arm64.zip">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-386.zip">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-macos-amd64.zip">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-macos-arm64.zip">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-amd64.zip">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-arm64.zip">Liên kết</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-386.zip">Liên kết</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Thêm thông tin về cài đặt, vui lòng tham khảo [Cài đặt](https://docs.gopeed.com/install.html)
|
||||
@@ -170,7 +184,7 @@ command:
|
||||
- android
|
||||
|
||||
```bash
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s -checklinkname=0" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
cd ui/flutter
|
||||
flutter build apk
|
||||
```
|
||||
|
||||
+75
-61
@@ -22,66 +22,80 @@ Gopeed(全称 Go Speed),直译过来中文名叫做`够快下载器`(不
|
||||
## 下载
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>运行平台</th>
|
||||
<th>安装包类型</th>
|
||||
<th>下载链接</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan=2>Windows</td>
|
||||
<td><code>EXE Installer</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64.zip">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Portable ZIP</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64-portable.zip">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MacOS</td>
|
||||
<td><code>DMG Installer</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-macos.dmg">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan=4>Linux</td>
|
||||
<td><code>Flathub</code></td>
|
||||
<td><a href="https://flathub.org/apps/com.gopeed.Gopeed">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SNAP</code></td>
|
||||
<td><a href="https://snapcraft.io/gopeed">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>DEB</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-amd64.deb">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>AppImage</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-x86_64.AppImage">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Android</td>
|
||||
<td><code>APK</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-android.apk">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>iOS</td>
|
||||
<td><code>IPA</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-ios.ipa">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Web</td>
|
||||
<td></td>
|
||||
<td><a href="https://github.com/GopeedLab/gopeed/releases/latest">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Docker</td>
|
||||
<td></td>
|
||||
<td><a href="https://hub.docker.com/r/liwei2633/gopeed">前往</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Windows</th>
|
||||
<th>MacOS</th>
|
||||
<th colspan="4">Linux</th>
|
||||
<th>Android</th>
|
||||
<th>iOS</th>
|
||||
<th>Docker</th>
|
||||
<th colspan="2">Qnap</th>
|
||||
<th colspan="8">Web</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>EXE</code></td>
|
||||
<td><code>Portable</code></td>
|
||||
<td><code>DMG</code></td>
|
||||
<td><code>Flathub</code></td>
|
||||
<td><code>SNAP</code></td>
|
||||
<td><code>DEB</code></td>
|
||||
<td><code>AppImage</code></td>
|
||||
<td><code>APK</code></td>
|
||||
<td><code>IPA</code></td>
|
||||
<td>-</td>
|
||||
<td colspan="2"><code>QPKG</code></td>
|
||||
<td colspan="3"><code>Windows</code></td>
|
||||
<td colspan="2"><code>MacOS</code></td>
|
||||
<td colspan="3"><code>Linux</code></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>-</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>amd64</td>
|
||||
<td>arm64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>386</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>386</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64-portable.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-macos.dmg">前往</a></td>
|
||||
<td><a href="https://flathub.org/apps/com.gopeed.Gopeed">前往</a></td>
|
||||
<td><a href="https://snapcraft.io/gopeed">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-amd64.deb">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-x86_64.AppImage">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-android.apk">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-ios.ipa">前往</a></td>
|
||||
<td><a href="https://hub.docker.com/r/liwei2633/gopeed">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-$version-qnap-amd64.qpkg">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-$version-qnap-arm64.qpkg">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-amd64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-arm64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-386.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-macos-amd64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-macos-arm64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-amd64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-arm64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-386.zip">前往</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
更多关于安装的内容请参考[安装文档](https://docs.gopeed.com/zh/install.html)
|
||||
@@ -174,7 +188,7 @@ gomobile init
|
||||
- android
|
||||
|
||||
```bash
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s -checklinkname=0" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
cd ui/flutter
|
||||
flutter build apk
|
||||
```
|
||||
|
||||
+75
-61
@@ -22,66 +22,80 @@ Gopeed(全稱 Go Speed),是一款使用`Golang`+`Flutter`編寫的高速
|
||||
## 下載
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>運行平台</th>
|
||||
<th>安裝包類型</th>
|
||||
<th>下載鏈接</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan=2>Windows</td>
|
||||
<td><code>EXE Installer</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64.zip">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Portable ZIP</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64-portable.zip">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MacOS</td>
|
||||
<td><code>DMG Installer</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-macos.dmg">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan=4>Linux</td>
|
||||
<td><code>Flathub</code></td>
|
||||
<td><a href="https://flathub.org/apps/com.gopeed.Gopeed">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SNAP</code></td>
|
||||
<td><a href="https://snapcraft.io/gopeed">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>DEB</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-amd64.deb">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>AppImage</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-x86_64.AppImage">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Android</td>
|
||||
<td><code>APK</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-android.apk">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>iOS</td>
|
||||
<td><code>IPA</code></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-ios.ipa">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Web</td>
|
||||
<td></td>
|
||||
<td><a href="https://github.com/GopeedLab/gopeed/releases/latest">前往</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Docker</td>
|
||||
<td></td>
|
||||
<td><a href="https://hub.docker.com/r/liwei2633/gopeed">前往</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Windows</th>
|
||||
<th>MacOS</th>
|
||||
<th colspan="4">Linux</th>
|
||||
<th>Android</th>
|
||||
<th>iOS</th>
|
||||
<th>Docker</th>
|
||||
<th colspan="2">Qnap</th>
|
||||
<th colspan="8">Web</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>EXE</code></td>
|
||||
<td><code>Portable</code></td>
|
||||
<td><code>DMG</code></td>
|
||||
<td><code>Flathub</code></td>
|
||||
<td><code>SNAP</code></td>
|
||||
<td><code>DEB</code></td>
|
||||
<td><code>AppImage</code></td>
|
||||
<td><code>APK</code></td>
|
||||
<td><code>IPA</code></td>
|
||||
<td>-</td>
|
||||
<td colspan="2"><code>QPKG</code></td>
|
||||
<td colspan="3"><code>Windows</code></td>
|
||||
<td colspan="2"><code>MacOS</code></td>
|
||||
<td colspan="3"><code>Linux</code></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>-</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>amd64</td>
|
||||
<td>arm64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>386</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>amd64</td>
|
||||
<td>386</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-windows-amd64-portable.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-macos.dmg">前往</a></td>
|
||||
<td><a href="https://flathub.org/apps/com.gopeed.Gopeed">前往</a></td>
|
||||
<td><a href="https://snapcraft.io/gopeed">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-amd64.deb">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-linux-x86_64.AppImage">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-android.apk">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=Gopeed-$version-ios.ipa">前往</a></td>
|
||||
<td><a href="https://hub.docker.com/r/liwei2633/gopeed">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-$version-qnap-amd64.qpkg">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-$version-qnap-arm64.qpkg">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-amd64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-arm64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-windows-386.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-macos-amd64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-macos-arm64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-amd64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-arm64.zip">前往</a></td>
|
||||
<td><a href="https://gopeed.com/api/download?tpl=gopeed-web-$version-linux-386.zip">前往</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
更多關於安裝的內容請參考[安裝文檔](https://docs.gopeed.com/zh/install.html)
|
||||
@@ -170,7 +184,7 @@ gomobile init
|
||||
- android
|
||||
|
||||
```bash
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s -checklinkname=0" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
cd ui/flutter
|
||||
flutter build apk
|
||||
```
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/browser"
|
||||
"github.com/shirou/gopsutil/v4/process"
|
||||
)
|
||||
|
||||
const identifier = "gopeed"
|
||||
|
||||
type Message struct {
|
||||
Method string `json:"method"`
|
||||
Params json.RawMessage `json:"params"`
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Code int `json:"code"`
|
||||
Data any `json:"data,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
var apiMap = map[string]func(params json.RawMessage) (data any, err error){
|
||||
"ping": func(params json.RawMessage) (data any, err error) {
|
||||
processes, err := process.Processes()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, p := range processes {
|
||||
name, err := p.Name()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.Contains(strings.ToLower(name), strings.ToLower(identifier)) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
},
|
||||
"create": func(params json.RawMessage) (data any, err error) {
|
||||
var strParams string
|
||||
if err = json.Unmarshal(params, &strParams); err != nil {
|
||||
return
|
||||
}
|
||||
err = browser.OpenURL(fmt.Sprintf("%s:///create?params=%s", identifier, strParams))
|
||||
return
|
||||
},
|
||||
}
|
||||
|
||||
func main() {
|
||||
for {
|
||||
// Read message length (first 4 bytes)
|
||||
var length uint32
|
||||
if err := binary.Read(os.Stdin, binary.NativeEndian, &length); err != nil {
|
||||
if err == io.EOF {
|
||||
// Connection closed by Chrome
|
||||
return
|
||||
}
|
||||
sendError("Failed to read message length: " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Read the message
|
||||
input := make([]byte, length)
|
||||
if _, err := io.ReadFull(os.Stdin, input); err != nil {
|
||||
sendError("Failed to read message: " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Parse message
|
||||
var message Message
|
||||
if err := json.Unmarshal(input, &message); err != nil {
|
||||
sendError("Failed to parse message: " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Handle request
|
||||
var data any
|
||||
var err error
|
||||
if handler, ok := apiMap[message.Method]; ok {
|
||||
data, err = handler(message.Params)
|
||||
} else {
|
||||
err = errors.New("Unknown method: " + message.Method)
|
||||
}
|
||||
if err != nil {
|
||||
sendError(err.Error())
|
||||
continue
|
||||
}
|
||||
sendResponse(0, data, "")
|
||||
}
|
||||
}
|
||||
|
||||
func sendResponse(code int, data interface{}, message string) {
|
||||
response := Response{
|
||||
Code: code,
|
||||
Data: data,
|
||||
Message: message,
|
||||
}
|
||||
|
||||
// Encode response
|
||||
responseBytes, err := json.Marshal(response)
|
||||
if err != nil {
|
||||
sendError("Failed to encode response: " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Write message length
|
||||
binary.Write(os.Stdout, binary.NativeEndian, uint32(len(responseBytes)))
|
||||
// Write message
|
||||
os.Stdout.Write(responseBytes)
|
||||
}
|
||||
|
||||
func sendError(msg string) {
|
||||
sendResponse(1, nil, msg)
|
||||
}
|
||||
+14
-11
@@ -1,12 +1,15 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
gopeed:
|
||||
container_name: gopeed
|
||||
ports:
|
||||
- "9999:9999" # HTTP port (host:container)
|
||||
image: liwei2633/gopeed
|
||||
volumes:
|
||||
- ~/gopeed/Downloads:/app/Downloads # mount download path
|
||||
#- ~/gopeed/storage:/app/storage # if you need to mount storage path, uncomment this line
|
||||
restart: unless-stopped
|
||||
gopeed:
|
||||
container_name: gopeed
|
||||
ports:
|
||||
- 9999:9999 # HTTP port (host:container)
|
||||
environment:
|
||||
- PUID=0
|
||||
- PGID=0
|
||||
- UMASK=022
|
||||
volumes:
|
||||
- ~/gopeed/Downloads:/app/Downloads # mount download path
|
||||
#- ~/gopeed/storage:/app/storage # if you need to mount storage path, uncomment this line
|
||||
restart: unless-stopped
|
||||
image: liwei2633/gopeed
|
||||
# command: -u Username -p Password # optional authentication
|
||||
@@ -24,6 +24,16 @@ require (
|
||||
golang.org/x/sync v0.9.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/ebitengine/purego v0.8.1 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
@@ -99,9 +109,11 @@ require (
|
||||
github.com/pion/turn/v4 v4.0.0 // indirect
|
||||
github.com/pion/webrtc/v4 v4.0.2 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
|
||||
github.com/protolambda/ctxlock v0.1.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.24.12
|
||||
github.com/skeema/knownhosts v1.2.0 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/tidwall/btree v1.7.0 // indirect
|
||||
@@ -113,7 +125,7 @@ require (
|
||||
golang.org/x/crypto v0.29.0 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/net v0.31.0 // indirect
|
||||
golang.org/x/sys v0.27.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/text v0.20.0 // indirect
|
||||
golang.org/x/time v0.8.0 // indirect
|
||||
golang.org/x/tools v0.27.0 // indirect
|
||||
|
||||
@@ -143,6 +143,8 @@ github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+m
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/ebitengine/purego v0.8.1 h1:sdRKd6plj7KYW33EH5As6YKfe8m9zbN9JMrOjNVF/BE=
|
||||
github.com/ebitengine/purego v0.8.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/edsrzf/mmap-go v1.2.0 h1:hXLYlkbaPzt1SaQk+anYwKSRNhufIDCchSPkUD6dD84=
|
||||
github.com/edsrzf/mmap-go v1.2.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
|
||||
github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0=
|
||||
@@ -187,6 +189,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
|
||||
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
|
||||
github.com/go-sourcemap/sourcemap v2.1.4+incompatible h1:a+iTbH5auLKxaNwQFg0B+TCYl6lbukKPc7b5x0n1s6Q=
|
||||
@@ -288,6 +292,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY=
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
|
||||
github.com/matoous/go-nanoid v1.5.0/go.mod h1:zyD2a71IubI24efhpvkJz+ZwfwagzgSO6UNiFsZKN7U=
|
||||
github.com/matoous/go-nanoid/v2 v2.0.0 h1:d19kur2QuLeHmJBkvYkFdhFBzLoo1XVm2GgTpL+9Tj0=
|
||||
github.com/matoous/go-nanoid/v2 v2.0.0/go.mod h1:FtS4aGPVfEkxKxhdWPAspZpZSh1cOjtM7Ej/So3hR0g=
|
||||
@@ -363,6 +369,8 @@ github.com/pion/webrtc/v4 v4.0.2 h1:fBwm5/hqSUybrCWl0DDBSTDrpbkcgkqpeLmXw9CsBQA=
|
||||
github.com/pion/webrtc/v4 v4.0.2/go.mod h1:moylBT2A4dNoEaYBCdV1nThM3TLwRHzWszIG+eSPaqQ=
|
||||
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
||||
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -370,6 +378,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c h1:NRoLoZvkBTKvR5gQLgA3e0hqjkY9u1wm+iOL45VN/qI=
|
||||
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
@@ -412,6 +422,8 @@ github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a
|
||||
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shirou/gopsutil/v4 v4.24.12 h1:qvePBOk20e0IKA1QXrIIU+jmk+zEiYVVx06WjBRlZo4=
|
||||
github.com/shirou/gopsutil/v4 v4.24.12/go.mod h1:DCtMPAad2XceTeIAbGyVfycbYQNBGk2P8cvDi7/VN9o=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
@@ -447,6 +459,10 @@ github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EU
|
||||
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
|
||||
@@ -458,6 +474,8 @@ github.com/xiaoqidun/setft v0.0.0-20220310121541-be86327699ad/go.mod h1:Jj8p9bgK
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
|
||||
go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
@@ -543,6 +561,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -552,6 +571,7 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -562,13 +582,18 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
|
||||
@@ -11,7 +11,9 @@ import (
|
||||
"github.com/GopeedLab/gopeed/pkg/util"
|
||||
"github.com/anacrolix/torrent"
|
||||
"github.com/anacrolix/torrent/metainfo"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -359,17 +361,34 @@ func (f *Fetcher) addTorrent(req *base.Request, fromUpload bool) (err error) {
|
||||
schema := util.ParseSchema(req.URL)
|
||||
if schema == "MAGNET" {
|
||||
f.torrent, err = client.AddMagnet(req.URL)
|
||||
} else if schema == "DATA" {
|
||||
_, data := util.ParseDataUri(req.URL)
|
||||
buf := bytes.NewBuffer(data)
|
||||
} else {
|
||||
var reader io.Reader
|
||||
if schema == "FILE" {
|
||||
fileUrl, _ := url.Parse(req.URL)
|
||||
filePath := fileUrl.Path[1:]
|
||||
reader, err = os.Open(filePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else if schema == "DATA" {
|
||||
_, data := util.ParseDataUri(req.URL)
|
||||
reader = bytes.NewBuffer(data)
|
||||
} else {
|
||||
reader, err = os.Open(req.URL)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer reader.(io.Closer).Close()
|
||||
}
|
||||
|
||||
var metaInfo *metainfo.MetaInfo
|
||||
metaInfo, err = metainfo.Load(buf)
|
||||
if err != nil {
|
||||
metaInfo, err = metainfo.Load(reader)
|
||||
// Hotfix for https://github.com/anacrolix/torrent/issues/992, ignore "expected EOF" error
|
||||
// TODO remove this after the issue is fixed
|
||||
if err != nil && !strings.Contains(err.Error(), "expected EOF") {
|
||||
return err
|
||||
}
|
||||
f.torrent, err = client.AddTorrent(metaInfo)
|
||||
} else {
|
||||
f.torrent, err = client.AddTorrentFromFile(req.URL)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
gohttp "net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
@@ -96,7 +97,7 @@ func doResolve(t *testing.T, fetcher fetcher.Fetcher) {
|
||||
Hash: "8a55cfbd5ca5d11507364765936c4f9e55b253ed",
|
||||
}
|
||||
if !reflect.DeepEqual(want, fetcher.Meta().Res) {
|
||||
t.Errorf("Resolve() got = %v, want %v", fetcher.Meta().Res, want)
|
||||
t.Errorf("Resolve Single File Resolve() got = %v, want %v", fetcher.Meta().Res, want)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -136,10 +137,29 @@ func doResolve(t *testing.T, fetcher fetcher.Fetcher) {
|
||||
Hash: "ccbc92b0cd8deec16a2ef4be242a8c9243b1cedb",
|
||||
}
|
||||
if !reflect.DeepEqual(want, fetcher.Meta().Res) {
|
||||
t.Errorf("Resolve() got = %v, want %v", fetcher.Meta().Res, want)
|
||||
t.Errorf("Resolve Multi Files Resolve() got = %v, want %v", fetcher.Meta().Res, want)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Resolve Unclean Torrent", func(t *testing.T) {
|
||||
err := fetcher.Resolve(&base.Request{
|
||||
URL: "./testdata/test.unclean.torrent",
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("Resolve Unclean Torrent Resolve() got = %v, want nil", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Resolve file scheme Torrent", func(t *testing.T) {
|
||||
file, _ := filepath.Abs("./testdata/test.unclean.torrent")
|
||||
uri := "file:///" + file
|
||||
err := fetcher.Resolve(&base.Request{
|
||||
URL: uri,
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("Resolve file scheme Torrent Resolve() got = %v, want nil", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestFetcherManager_ParseName(t *testing.T) {
|
||||
|
||||
Binary file not shown.
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
@@ -25,6 +26,9 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
const connectTimeout = 15 * time.Second
|
||||
const readTimeout = 15 * time.Second
|
||||
|
||||
type RequestError struct {
|
||||
Code int
|
||||
Msg string
|
||||
@@ -103,9 +107,9 @@ func (f *Fetcher) Resolve(req *base.Request) error {
|
||||
if base.HttpCodePartialContent == httpResp.StatusCode || (base.HttpCodeOK == httpResp.StatusCode && httpResp.Header.Get(base.HttpHeaderAcceptRanges) == base.HttpHeaderBytes && strings.HasPrefix(httpResp.Header.Get(base.HttpHeaderContentRange), base.HttpHeaderBytes)) {
|
||||
// response 206 status code, support breakpoint continuation
|
||||
res.Range = true
|
||||
// 解析资源大小: bytes 0-1000/1001 => 1001
|
||||
// parse content length from Content-Range header, eg: bytes 0-1000/1001 or bytes 0-0/*
|
||||
contentTotal := path.Base(httpResp.Header.Get(base.HttpHeaderContentRange))
|
||||
if contentTotal != "" {
|
||||
if contentTotal != "" && contentTotal != "*" {
|
||||
parse, err := strconv.ParseInt(contentTotal, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -146,7 +150,7 @@ func (f *Fetcher) Resolve(req *base.Request) error {
|
||||
file.Name = filename
|
||||
}
|
||||
}
|
||||
// Get file filePath by URL
|
||||
// get file filePath by URL
|
||||
if file.Name == "" {
|
||||
file.Name = path.Base(httpReq.URL.Path)
|
||||
}
|
||||
@@ -162,9 +166,6 @@ func (f *Fetcher) Resolve(req *base.Request) error {
|
||||
func (f *Fetcher) Create(opts *base.Options) error {
|
||||
f.meta.Opts = opts
|
||||
|
||||
if err := base.ParseReqExtra[fhttp.ReqExtra](f.meta.Req); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := base.ParseOptsExtra[fhttp.OptsExtra](f.meta.Opts); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -198,6 +199,12 @@ func (f *Fetcher) Start() (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Avoid request extra modified by extension
|
||||
if err = base.ParseReqExtra[fhttp.ReqExtra](f.meta.Req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if f.chunks == nil {
|
||||
f.chunks = f.splitChunk()
|
||||
}
|
||||
@@ -247,23 +254,42 @@ func (f *Fetcher) Wait() (err error) {
|
||||
return <-f.doneCh
|
||||
}
|
||||
|
||||
type fetchResult struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (f *Fetcher) fetch() {
|
||||
var ctx context.Context
|
||||
ctx, f.cancel = context.WithCancel(context.Background())
|
||||
f.eg, _ = errgroup.WithContext(ctx)
|
||||
chunkErrs := make([]error, len(f.chunks))
|
||||
for i := 0; i < len(f.chunks); i++ {
|
||||
i := i
|
||||
f.eg.Go(func() error {
|
||||
return f.fetchChunk(i, ctx)
|
||||
err := f.fetchChunk(i, ctx)
|
||||
// if canceled, fail fast
|
||||
if errors.Is(err, context.Canceled) {
|
||||
return err
|
||||
}
|
||||
chunkErrs[i] = err
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := f.eg.Wait()
|
||||
// check if canceled
|
||||
if errors.Is(err, context.Canceled) {
|
||||
// error returned only if canceled, just return
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// check all fetch results, if any error, return
|
||||
for _, chunkErr := range chunkErrs {
|
||||
if chunkErr != nil {
|
||||
err = chunkErr
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
f.file.Close()
|
||||
// Update file last modified time
|
||||
if f.config.UseServerCtime && f.meta.Res.Files[0].Ctime != nil {
|
||||
@@ -286,24 +312,11 @@ func (f *Fetcher) fetchChunk(index int, ctx context.Context) (err error) {
|
||||
for {
|
||||
// if chunk is completed, return
|
||||
if f.meta.Res.Range && chunk.Downloaded >= chunk.End-chunk.Begin+1 {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
if chunk.retryTimes >= maxRetries {
|
||||
if !f.meta.Res.Range {
|
||||
return
|
||||
}
|
||||
// check if all failed
|
||||
allFailed := true
|
||||
for _, c := range f.chunks {
|
||||
if chunk.Downloaded < chunk.End-chunk.Begin+1 && c.retryTimes < maxRetries {
|
||||
allFailed = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if allFailed {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -330,10 +343,9 @@ func (f *Fetcher) fetchChunk(index int, ctx context.Context) (err error) {
|
||||
err = NewRequestError(resp.StatusCode, resp.Status)
|
||||
return err
|
||||
}
|
||||
// Http request success, reset retry times
|
||||
chunk.retryTimes = 0
|
||||
reader := NewTimeoutReader(resp.Body, readTimeout)
|
||||
for {
|
||||
n, err := resp.Body.Read(buf)
|
||||
n, err := reader.Read(buf)
|
||||
if n > 0 {
|
||||
_, err := f.file.WriteAt(buf[:n], chunk.Begin+chunk.Downloaded)
|
||||
if err != nil {
|
||||
@@ -348,7 +360,6 @@ func (f *Fetcher) fetchChunk(index int, ctx context.Context) (err error) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
if err != nil {
|
||||
// If canceled, do not retry
|
||||
@@ -416,6 +427,10 @@ func (f *Fetcher) buildRequest(ctx context.Context, req *base.Request) (httpReq
|
||||
return
|
||||
}
|
||||
httpReq.Header = headers
|
||||
// Override Host header
|
||||
if host := headers.Get(base.HttpHeaderHost); host != "" {
|
||||
httpReq.Host = host
|
||||
}
|
||||
return httpReq, nil
|
||||
}
|
||||
|
||||
@@ -449,6 +464,9 @@ func (f *Fetcher) splitChunk() (chunks []*chunk) {
|
||||
|
||||
func (f *Fetcher) buildClient() *http.Client {
|
||||
transport := &http.Transport{
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: connectTimeout,
|
||||
}).DialContext,
|
||||
Proxy: f.ctl.GetProxy(f.meta.Req.Proxy),
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: f.meta.Req.SkipVerifyCert,
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"net"
|
||||
gohttp "net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -59,6 +60,21 @@ func TestFetcher_Resolve(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetcher_ResolveWithHostHeader(t *testing.T) {
|
||||
fetcher := buildFetcher()
|
||||
err := fetcher.Resolve(&base.Request{
|
||||
URL: "https://bing.com",
|
||||
Extra: &http.ReqExtra{
|
||||
Header: map[string]string{
|
||||
"Host": "test",
|
||||
},
|
||||
},
|
||||
})
|
||||
if err == nil || !strings.Contains(err.Error(), "400") {
|
||||
t.Errorf("Resolve() got = %v, want %v", err, "400")
|
||||
}
|
||||
}
|
||||
|
||||
func testResolve(startTestServer func() net.Listener, path string, want *base.Resource, t *testing.T) {
|
||||
listener := startTestServer()
|
||||
defer listener.Close()
|
||||
@@ -132,6 +148,14 @@ func TestFetcher_DownloadLimit(t *testing.T) {
|
||||
downloadNormal(listener, 8, t)
|
||||
}
|
||||
|
||||
func TestFetcher_DownloadResponseBodyReadTimeout(t *testing.T) {
|
||||
listener := test.StartTestLimitServer(16, readTimeout.Milliseconds()+5000)
|
||||
defer listener.Close()
|
||||
|
||||
downloadError(listener, 1, t)
|
||||
downloadError(listener, 4, t)
|
||||
}
|
||||
|
||||
func TestFetcher_DownloadResume(t *testing.T) {
|
||||
listener := test.StartTestFileServer()
|
||||
defer listener.Close()
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TimeoutReader struct {
|
||||
reader io.Reader
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
func NewTimeoutReader(r io.Reader, timeout time.Duration) *TimeoutReader {
|
||||
return &TimeoutReader{
|
||||
reader: r,
|
||||
timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
func (tr *TimeoutReader) Read(p []byte) (n int, err error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), tr.timeout)
|
||||
defer cancel()
|
||||
|
||||
done := make(chan struct{})
|
||||
var readErr error
|
||||
var bytesRead int
|
||||
|
||||
go func() {
|
||||
bytesRead, readErr = tr.reader.Read(p)
|
||||
close(done)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
return bytesRead, readErr
|
||||
case <-ctx.Done():
|
||||
return 0, ctx.Err()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestTimeoutReader_Read(t *testing.T) {
|
||||
data := []byte("Hello, World!")
|
||||
reader := bytes.NewReader(data)
|
||||
timeoutReader := NewTimeoutReader(reader, 1*time.Second)
|
||||
|
||||
buf := make([]byte, len(data))
|
||||
n, err := timeoutReader.Read(buf)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error, got %v", err)
|
||||
}
|
||||
if n != len(data) {
|
||||
t.Fatalf("expected to read %d bytes, read %d", len(data), n)
|
||||
}
|
||||
if !bytes.Equal(buf, data) {
|
||||
t.Fatalf("expected %s, got %s", data, buf)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeoutReader_ReadTimeout(t *testing.T) {
|
||||
reader := &slowReader{delay: 2 * time.Second}
|
||||
timeoutReader := NewTimeoutReader(reader, 1*time.Second)
|
||||
|
||||
buf := make([]byte, 8192)
|
||||
_, err := timeoutReader.Read(buf)
|
||||
if err == nil {
|
||||
t.Fatal("expected timeout error, got nil")
|
||||
}
|
||||
if !errors.Is(err, context.DeadlineExceeded) {
|
||||
t.Fatalf("expected %v, got %v", context.DeadlineExceeded, err)
|
||||
}
|
||||
}
|
||||
|
||||
type slowReader struct {
|
||||
delay time.Duration
|
||||
}
|
||||
|
||||
func (sr *slowReader) Read(p []byte) (n int, err error) {
|
||||
time.Sleep(sr.delay)
|
||||
return 0, io.EOF
|
||||
}
|
||||
+30
-19
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/GopeedLab/gopeed/pkg/base"
|
||||
"github.com/armon/go-socks5"
|
||||
@@ -36,7 +37,7 @@ const (
|
||||
)
|
||||
|
||||
func StartTestFileServer() net.Listener {
|
||||
return startTestServer(func() http.Handler {
|
||||
return startTestServer(func(sl *shutdownListener) http.Handler {
|
||||
return http.FileServer(http.Dir(Dir))
|
||||
})
|
||||
}
|
||||
@@ -52,7 +53,7 @@ func (s *SlowFileServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func StartTestSlowFileServer(delay time.Duration) net.Listener {
|
||||
return startTestServer(func() http.Handler {
|
||||
return startTestServer(func(sl *shutdownListener) http.Handler {
|
||||
return &SlowFileServer{
|
||||
delay: delay,
|
||||
handler: http.FileServer(http.Dir(Dir)),
|
||||
@@ -61,7 +62,7 @@ func StartTestSlowFileServer(delay time.Duration) net.Listener {
|
||||
}
|
||||
|
||||
func StartTestCustomServer() net.Listener {
|
||||
return startTestServer(func() http.Handler {
|
||||
return startTestServer(func(sl *shutdownListener) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/"+BuildName, func(writer http.ResponseWriter, request *http.Request) {
|
||||
file, err := os.Open(BuildFile)
|
||||
@@ -88,7 +89,7 @@ func StartTestCustomServer() net.Listener {
|
||||
|
||||
func StartTestRetryServer() net.Listener {
|
||||
counter := 0
|
||||
return startTestServer(func() http.Handler {
|
||||
return startTestServer(func(sl *shutdownListener) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/"+BuildName, func(writer http.ResponseWriter, request *http.Request) {
|
||||
counter++
|
||||
@@ -108,7 +109,7 @@ func StartTestRetryServer() net.Listener {
|
||||
}
|
||||
|
||||
func StartTestPostServer() net.Listener {
|
||||
return startTestServer(func() http.Handler {
|
||||
return startTestServer(func(sl *shutdownListener) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/"+BuildName, func(writer http.ResponseWriter, request *http.Request) {
|
||||
if request.Method == "POST" && request.Header.Get("Authorization") != "" {
|
||||
@@ -132,7 +133,7 @@ func StartTestPostServer() net.Listener {
|
||||
|
||||
func StartTestErrorServer() net.Listener {
|
||||
counter := 0
|
||||
return startTestServer(func() http.Handler {
|
||||
return startTestServer(func(sl *shutdownListener) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/"+BuildName, func(writer http.ResponseWriter, request *http.Request) {
|
||||
counter++
|
||||
@@ -149,7 +150,7 @@ func StartTestErrorServer() net.Listener {
|
||||
func StartTestLimitServer(maxConnections int32, delay int64) net.Listener {
|
||||
var connections atomic.Int32
|
||||
|
||||
return startTestServer(func() http.Handler {
|
||||
return startTestServer(func(sl *shutdownListener) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/"+BuildName, func(writer http.ResponseWriter, request *http.Request) {
|
||||
defer func() {
|
||||
@@ -165,12 +166,14 @@ func StartTestLimitServer(maxConnections int32, delay int64) net.Listener {
|
||||
if r == "" {
|
||||
writer.Header().Set("Content-Length", fmt.Sprintf("%d", BuildSize))
|
||||
writer.WriteHeader(200)
|
||||
(writer.(http.Flusher)).Flush()
|
||||
|
||||
file, err := os.Open(BuildFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
slowCopy(writer, file, delay)
|
||||
slowCopy(sl, writer, file, delay)
|
||||
} else {
|
||||
// split range
|
||||
s := strings.Split(r, "=")
|
||||
@@ -204,6 +207,8 @@ func StartTestLimitServer(maxConnections int32, delay int64) net.Listener {
|
||||
writer.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", start, end, BuildSize))
|
||||
writer.Header().Set("Accept-Ranges", "bytes")
|
||||
writer.WriteHeader(206)
|
||||
(writer.(http.Flusher)).Flush()
|
||||
|
||||
file, err := os.Open(BuildFile)
|
||||
if err != nil {
|
||||
writer.WriteHeader(500)
|
||||
@@ -211,7 +216,7 @@ func StartTestLimitServer(maxConnections int32, delay int64) net.Listener {
|
||||
}
|
||||
defer file.Close()
|
||||
file.Seek(start, 0)
|
||||
slowCopyN(writer, file, end-start+1, delay)
|
||||
slowCopyN(sl, writer, file, end-start+1, delay)
|
||||
}
|
||||
})
|
||||
return mux
|
||||
@@ -219,9 +224,12 @@ func StartTestLimitServer(maxConnections int32, delay int64) net.Listener {
|
||||
}
|
||||
|
||||
// slowCopyN copies n bytes from src to dst, speed limit is bytes per second
|
||||
func slowCopy(dst io.Writer, src io.Reader, delay int64) (written int64, err error) {
|
||||
func slowCopy(sl *shutdownListener, dst io.Writer, src io.Reader, delay int64) (written int64, err error) {
|
||||
buf := make([]byte, 32*1024)
|
||||
for {
|
||||
if sl.isShutdown {
|
||||
return 0, errors.New("server shutdown")
|
||||
}
|
||||
nr, er := src.Read(buf)
|
||||
if nr > 0 {
|
||||
nw, ew := dst.Write(buf[0:nr])
|
||||
@@ -250,8 +258,8 @@ func slowCopy(dst io.Writer, src io.Reader, delay int64) (written int64, err err
|
||||
return written, err
|
||||
}
|
||||
|
||||
func slowCopyN(dst io.Writer, src io.Reader, n int64, delay int64) (written int64, err error) {
|
||||
written, err = slowCopy(dst, io.LimitReader(src, n), delay)
|
||||
func slowCopyN(sl *shutdownListener, dst io.Writer, src io.Reader, n int64, delay int64) (written int64, err error) {
|
||||
written, err = slowCopy(sl, dst, io.LimitReader(src, n), delay)
|
||||
if written == n {
|
||||
return n, nil
|
||||
}
|
||||
@@ -262,7 +270,7 @@ func slowCopyN(dst io.Writer, src io.Reader, n int64, delay int64) (written int6
|
||||
return
|
||||
}
|
||||
|
||||
func startTestServer(serverHandle func() http.Handler) net.Listener {
|
||||
func startTestServer(serverHandle func(sl *shutdownListener) http.Handler) net.Listener {
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -272,7 +280,7 @@ func startTestServer(serverHandle func() http.Handler) net.Listener {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
// 随机生成一个文件
|
||||
// Write random data
|
||||
l := int64(8192)
|
||||
buf := make([]byte, l)
|
||||
size := int64(0)
|
||||
@@ -289,21 +297,24 @@ func startTestServer(serverHandle func() http.Handler) net.Listener {
|
||||
size += l
|
||||
}
|
||||
server := &http.Server{}
|
||||
server.Handler = serverHandle()
|
||||
go server.Serve(listener)
|
||||
|
||||
return &shutdownListener{
|
||||
sl := &shutdownListener{
|
||||
server: server,
|
||||
Listener: listener,
|
||||
}
|
||||
server.Handler = serverHandle(sl)
|
||||
go server.Serve(listener)
|
||||
|
||||
return sl
|
||||
}
|
||||
|
||||
type shutdownListener struct {
|
||||
server *http.Server
|
||||
server *http.Server
|
||||
isShutdown bool
|
||||
net.Listener
|
||||
}
|
||||
|
||||
func (c *shutdownListener) Close() error {
|
||||
c.isShutdown = true
|
||||
closeErr := c.server.Shutdown(context.Background())
|
||||
if err := ifExistAndRemove(BuildFile); err != nil {
|
||||
fmt.Println(err)
|
||||
|
||||
@@ -15,6 +15,7 @@ const (
|
||||
HttpCodeOK = 200
|
||||
HttpCodePartialContent = 206
|
||||
|
||||
HttpHeaderHost = "Host"
|
||||
HttpHeaderRange = "Range"
|
||||
HttpHeaderAcceptRanges = "Accept-Ranges"
|
||||
HttpHeaderContentLength = "Content-Length"
|
||||
|
||||
+28
-16
@@ -204,33 +204,29 @@ func (d *Downloader) Setup() error {
|
||||
|
||||
current := task.fetcher.Progress().TotalDownloaded()
|
||||
tick := float64(d.cfg.RefreshInterval) / 1000
|
||||
downloadDataChanged := false
|
||||
if task.Status == base.DownloadStatusRunning {
|
||||
downloadDataChanged = current != task.Progress.Downloaded
|
||||
task.Progress.Used = task.timer.Used()
|
||||
task.Progress.Speed = task.calcSpeed(task.speedArr, current-task.Progress.Downloaded, tick)
|
||||
task.Progress.Downloaded = current
|
||||
}
|
||||
|
||||
uploadDataChanged := false
|
||||
if task.Uploading {
|
||||
uploader := task.fetcher.(fetcher.Uploader)
|
||||
currentUploaded := uploader.UploadedBytes()
|
||||
uploadDataChanged = currentUploaded != task.Progress.Uploaded
|
||||
task.Progress.UploadSpeed = task.calcSpeed(task.uploadSpeedArr, currentUploaded-task.Progress.Uploaded, tick)
|
||||
task.Progress.Uploaded = currentUploaded
|
||||
}
|
||||
d.emit(EventKeyProgress, task)
|
||||
|
||||
// store fetcher progress
|
||||
data, err := task.fetcherManager.Store(task.fetcher)
|
||||
if err != nil {
|
||||
d.Logger.Error().Stack().Err(err).Msgf("serialize fetcher failed: %s", task.ID)
|
||||
return
|
||||
}
|
||||
if err := d.storage.Put(bucketSave, task.ID, data); err != nil {
|
||||
d.Logger.Error().Stack().Err(err).Msgf("persist fetcher failed: %s", task.ID)
|
||||
return
|
||||
}
|
||||
if err := d.storage.Put(bucketTask, task.ID, task); err != nil {
|
||||
d.Logger.Error().Stack().Err(err).Msgf("persist task failed: %s", task.ID)
|
||||
// store fetcher progress when download/upload data changed
|
||||
if !downloadDataChanged && !uploadDataChanged {
|
||||
return
|
||||
}
|
||||
d.saveTask(task)
|
||||
}()
|
||||
}
|
||||
}
|
||||
@@ -273,6 +269,23 @@ func (d *Downloader) setupFetcher(fm fetcher.FetcherManager, fetcher fetcher.Fet
|
||||
fetcher.Setup(ctl)
|
||||
}
|
||||
|
||||
func (d *Downloader) saveTask(task *Task) error {
|
||||
data, err := task.fetcherManager.Store(task.fetcher)
|
||||
if err != nil {
|
||||
d.Logger.Error().Stack().Err(err).Msgf("serialize fetcher failed: %s", task.ID)
|
||||
return err
|
||||
}
|
||||
if err := d.storage.Put(bucketSave, task.ID, data); err != nil {
|
||||
d.Logger.Error().Stack().Err(err).Msgf("persist fetcher failed: %s", task.ID)
|
||||
return err
|
||||
}
|
||||
if err := d.storage.Put(bucketTask, task.ID, task); err != nil {
|
||||
d.Logger.Error().Stack().Err(err).Msgf("persist task failed: %s", task.ID)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Downloader) Resolve(req *base.Request) (rr *ResolveResult, err error) {
|
||||
rrId, err := gonanoid.New()
|
||||
if err != nil {
|
||||
@@ -813,7 +826,7 @@ func (d *Downloader) watch(task *Task) {
|
||||
}
|
||||
|
||||
// When delete a not resolved task, need check if the task resource is nil
|
||||
if task.Meta.Res == nil {
|
||||
if task.Meta.Res == nil || d.GetTask(task.ID) == nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1005,8 +1018,6 @@ func (d *Downloader) doStart(task *Task) (err error) {
|
||||
return
|
||||
}
|
||||
isCreate = task.Status == base.DownloadStatusReady
|
||||
|
||||
d.triggerOnStart(task)
|
||||
task.updateStatus(base.DownloadStatusRunning)
|
||||
|
||||
return
|
||||
@@ -1023,6 +1034,7 @@ func (d *Downloader) doStart(task *Task) (err error) {
|
||||
task.lock.Lock()
|
||||
defer task.lock.Unlock()
|
||||
|
||||
d.triggerOnStart(task)
|
||||
if task.Meta.Res == nil {
|
||||
err := task.fetcher.Resolve(task.Meta.Req)
|
||||
if err != nil {
|
||||
@@ -1064,7 +1076,7 @@ func (d *Downloader) doStart(task *Task) (err error) {
|
||||
if err := task.fetcher.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.storage.Put(bucketTask, task.ID, task.clone()); err != nil {
|
||||
if err := d.saveTask(task); err != nil {
|
||||
return err
|
||||
}
|
||||
d.emit(EventKeyStart, task)
|
||||
|
||||
@@ -702,20 +702,22 @@ type OnDoneContext struct {
|
||||
Task *Task `json:"task"`
|
||||
}
|
||||
|
||||
// ExtensionTask is a wrapper of Task, it's used to interact with extension scripts.
|
||||
// Avoid extension scripts modifying task directly, use ExtensionTask to encapsulate task,
|
||||
// only some fields can be modified, such as request info.
|
||||
type ExtensionTask struct {
|
||||
*Task
|
||||
|
||||
download *Downloader
|
||||
|
||||
*Task
|
||||
}
|
||||
|
||||
func NewExtensionTask(download *Downloader, task *Task) *ExtensionTask {
|
||||
// restricts extension scripts to only modify request info
|
||||
newTask := task.clone()
|
||||
// Assign the pointer of the properties that the extension supports modification
|
||||
newTask.Meta = task.Meta
|
||||
newTask.Status = task.Status
|
||||
newTask.Meta.Req = task.Meta.Req
|
||||
return &ExtensionTask{
|
||||
Task: newTask,
|
||||
download: download,
|
||||
Task: newTask,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
|
||||
func ParseSchema(url string) string {
|
||||
index := strings.Index(url, ":")
|
||||
// if no schema or windows path like C:\a.txt, return FILE
|
||||
if index == -1 || index == 1 {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -68,3 +68,6 @@ windows/flutter/generated_plugins.cmake
|
||||
# Hive database files
|
||||
database.hive
|
||||
database.lock
|
||||
|
||||
assets/host/host
|
||||
assets/host/host.exe
|
||||
@@ -44,7 +44,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "com.gopeed"
|
||||
applicationId "com.gopeed.gopeed"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
||||
minSdkVersion 21
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.gopeed">
|
||||
package="com.gopeed.gopeed">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.gopeed">
|
||||
package="com.gopeed.gopeed">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.gopeed
|
||||
package com.gopeed.gopeed
|
||||
|
||||
import androidx.annotation.NonNull
|
||||
import com.gopeed.libgopeed.Libgopeed
|
||||
@@ -1,5 +1,5 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.gopeed">
|
||||
package="com.gopeed.gopeed">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Whitespace-only changes.
@@ -32,6 +32,13 @@ target 'Runner' do
|
||||
use_modular_headers!
|
||||
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
|
||||
# share_handler addition start
|
||||
target 'ShareExtension' do
|
||||
inherit! :search_paths
|
||||
pod "share_handler_ios_models", :path => ".symlinks/plugins/share_handler_ios/ios/Models"
|
||||
end
|
||||
# share_handler addition end
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0C585CBA2D41E28900FF2EC0 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C585CB92D41E28900FF2EC0 /* ShareViewController.swift */; };
|
||||
0C585CBD2D41E28900FF2EC0 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = 0C585CBC2D41E28900FF2EC0 /* Base */; };
|
||||
0C585CC12D41E28900FF2EC0 /* ShareExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0C585CB72D41E28900FF2EC0 /* ShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||
@@ -20,7 +23,28 @@
|
||||
DCA5B0FA95A8007ADEDACA1B /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70BC8D37FAC641C7F20125E8 /* Pods_Runner.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
0C585CBF2D41E28900FF2EC0 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 0C585CB62D41E28900FF2EC0;
|
||||
remoteInfo = ShareExtension;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
0C585CC22D41E28900FF2EC0 /* Embed Foundation Extensions */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
0C585CC12D41E28900FF2EC0 /* ShareExtension.appex in Embed Foundation Extensions */,
|
||||
);
|
||||
name = "Embed Foundation Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 8;
|
||||
@@ -35,7 +59,13 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
029EF293EAA92EB3D18BBF19 /* libresolv.tbd */ = {isa = PBXFileReference; includeInIndex = 1; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = "<group>"; };
|
||||
029EF293EAA92EB3D18BBF19 /* libresolv.tbd */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = "<group>"; };
|
||||
0C585CB72D41E28900FF2EC0 /* ShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0C585CB92D41E28900FF2EC0 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
|
||||
0C585CBC2D41E28900FF2EC0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
|
||||
0C585CBE2D41E28900FF2EC0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
0C585CC72D41E36800FF2EC0 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||
0C585CC82D41E38D00FF2EC0 /* ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ShareExtension.entitlements; sourceTree = "<group>"; };
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
25B61E78A388C87913468FD6 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
@@ -58,6 +88,13 @@
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
0C585CB42D41E28900FF2EC0 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -72,6 +109,17 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
0C585CB82D41E28900FF2EC0 /* ShareExtension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0C585CC82D41E38D00FF2EC0 /* ShareExtension.entitlements */,
|
||||
0C585CB92D41E28900FF2EC0 /* ShareViewController.swift */,
|
||||
0C585CBB2D41E28900FF2EC0 /* MainInterface.storyboard */,
|
||||
0C585CBE2D41E28900FF2EC0 /* Info.plist */,
|
||||
);
|
||||
path = ShareExtension;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -88,6 +136,7 @@
|
||||
children = (
|
||||
9740EEB11CF90186004384FC /* Flutter */,
|
||||
97C146F01CF9000F007C117D /* Runner */,
|
||||
0C585CB82D41E28900FF2EC0 /* ShareExtension */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
ADF7F433B4BC23D6C18AB78B /* Pods */,
|
||||
B4A1CBAC5AA50208793CFF34 /* Frameworks */,
|
||||
@@ -98,6 +147,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97C146EE1CF9000F007C117D /* Runner.app */,
|
||||
0C585CB72D41E28900FF2EC0 /* ShareExtension.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -105,6 +155,7 @@
|
||||
97C146F01CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0C585CC72D41E36800FF2EC0 /* Runner.entitlements */,
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
||||
@@ -141,6 +192,23 @@
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
0C585CB62D41E28900FF2EC0 /* ShareExtension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0C585CC62D41E28900FF2EC0 /* Build configuration list for PBXNativeTarget "ShareExtension" */;
|
||||
buildPhases = (
|
||||
0C585CB32D41E28900FF2EC0 /* Sources */,
|
||||
0C585CB42D41E28900FF2EC0 /* Frameworks */,
|
||||
0C585CB52D41E28900FF2EC0 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = ShareExtension;
|
||||
productName = ShareExtension;
|
||||
productReference = 0C585CB72D41E28900FF2EC0 /* ShareExtension.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
97C146ED1CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
@@ -150,6 +218,7 @@
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
0C585CC22D41E28900FF2EC0 /* Embed Foundation Extensions */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
DDA801E9D83E2E88398514D3 /* [CP] Embed Pods Frameworks */,
|
||||
@@ -157,6 +226,7 @@
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
0C585CC02D41E28900FF2EC0 /* PBXTargetDependency */,
|
||||
);
|
||||
name = Runner;
|
||||
productName = Runner;
|
||||
@@ -169,9 +239,13 @@
|
||||
97C146E61CF9000F007C117D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1540;
|
||||
LastUpgradeCheck = 1430;
|
||||
ORGANIZATIONNAME = "";
|
||||
TargetAttributes = {
|
||||
0C585CB62D41E28900FF2EC0 = {
|
||||
CreatedOnToolsVersion = 15.4;
|
||||
};
|
||||
97C146ED1CF9000F007C117D = {
|
||||
CreatedOnToolsVersion = 7.3.1;
|
||||
LastSwiftMigration = 1100;
|
||||
@@ -192,11 +266,20 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
97C146ED1CF9000F007C117D /* Runner */,
|
||||
0C585CB62D41E28900FF2EC0 /* ShareExtension */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
0C585CB52D41E28900FF2EC0 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0C585CBD2D41E28900FF2EC0 /* Base in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
97C146EC1CF9000F007C117D /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -284,6 +367,14 @@
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
0C585CB32D41E28900FF2EC0 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0C585CBA2D41E28900FF2EC0 /* ShareViewController.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
97C146EA1CF9000F007C117D /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -295,7 +386,23 @@
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
0C585CC02D41E28900FF2EC0 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 0C585CB62D41E28900FF2EC0 /* ShareExtension */;
|
||||
targetProxy = 0C585CBF2D41E28900FF2EC0 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
0C585CBB2D41E28900FF2EC0 /* MainInterface.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
0C585CBC2D41E28900FF2EC0 /* Base */,
|
||||
);
|
||||
name = MainInterface.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
@@ -315,6 +422,123 @@
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
0C585CC32D41E28900FF2EC0 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = JH48DS925K;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = ShareExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.5;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.gopeed.gopeed.ShareExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0C585CC42D41E28900FF2EC0 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = JH48DS925K;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = ShareExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.5;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.gopeed.gopeed.ShareExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
0C585CC52D41E28900FF2EC0 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = JH48DS925K;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = ShareExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.5;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.gopeed.gopeed.ShareExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Profile;
|
||||
};
|
||||
249021D3217E4FDB00AE95B9 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@@ -369,8 +593,10 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = JH48DS925K;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -379,7 +605,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.gopeed;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.gopeed.gopeed;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@@ -498,8 +724,10 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = JH48DS925K;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -508,7 +736,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.gopeed;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.gopeed.gopeed;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
@@ -521,8 +749,10 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = JH48DS925K;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -531,7 +761,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.gopeed;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.gopeed.gopeed;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@@ -542,6 +772,16 @@
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
0C585CC62D41E28900FF2EC0 /* Build configuration list for PBXNativeTarget "ShareExtension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0C585CC32D41E28900FF2EC0 /* Debug */,
|
||||
0C585CC42D41E28900FF2EC0 /* Release */,
|
||||
0C585CC52D41E28900FF2EC0 /* Profile */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
||||
@@ -1,54 +1,106 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Gopeed</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true />
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Gopeed</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true />
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true />
|
||||
</dict>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false />
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true />
|
||||
|
||||
<!-- Add for share_handler start -->
|
||||
<!-- The 'NSUserActivityTypes' key is only needed if you plan to use the recordSentMessage API
|
||||
allowing for conversations to show up as direct share suggestions -->
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array>
|
||||
<string>INSendMessageIntent</string>
|
||||
</array>
|
||||
|
||||
<!-- Uncomment below lines if you want to use a custom group id rather than the default. Set it
|
||||
in Build Settings -> User-Defined -->
|
||||
<!-- <key>AppGroupId</key>
|
||||
<string>$(CUSTOM_GROUP_ID)</string> -->
|
||||
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>Photos can be shared to and used in this app</string>
|
||||
|
||||
<!-- Optional: Add/Customize for AirDrop support -->
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<string>No</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>ShareHandler</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.file-url</string>
|
||||
<string>public.image</string>
|
||||
<string>public.text</string>
|
||||
<string>public.movie</string>
|
||||
<string>public.url</string>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
<!-- Add for share_handler end -->
|
||||
</dict>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.com.gopeed.gopeed</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="j1y-V4-xli">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Share View Controller-->
|
||||
<scene sceneID="ceB-am-kn3">
|
||||
<objects>
|
||||
<viewController id="j1y-V4-xli" customClass="ShareViewController" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" opaque="NO" contentMode="scaleToFill" id="wbc-yd-nQP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<viewLayoutGuide key="safeArea" id="1Xd-am-t49"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="CEy-Cv-SGf" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<!-- Uncomment below lines if you want to use a custom group id rather than the default. Set it
|
||||
in Build Settings -> User-Defined -->
|
||||
<!-- <key>AppGroupId</key>
|
||||
<string>$(CUSTOM_GROUP_ID)</string> -->
|
||||
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<!-- Add supported message intent if you support sharing to a specific conversation - start -->
|
||||
<key>IntentsSupported</key>
|
||||
<array>
|
||||
<string>INSendMessageIntent</string>
|
||||
</array>
|
||||
<!-- Add supported message intent if you support sharing to a specific conversation
|
||||
(registered via the recordSentMessage api call) - end -->
|
||||
<key>NSExtensionActivationRule</key>
|
||||
<!-- Comment or delete the TRUEPREDICATE NSExtensionActivationRule that only works in
|
||||
development mode -->
|
||||
<!-- <string>TRUEPREDICATE</string> -->
|
||||
<!-- Add a new NSExtensionActivationRule. The rule below will allow sharing one or more file
|
||||
of any type, url, or text content, You can modify these rules to your liking for which types
|
||||
of share content, as well as how many your app can handle -->
|
||||
<string>SUBQUERY ( extensionItems, $extensionItem, SUBQUERY ( $extensionItem.attachments,
|
||||
$attachment, ( ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.file-url"
|
||||
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image" || ANY
|
||||
$attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.text" || ANY
|
||||
$attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.movie" || ANY
|
||||
$attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.url" ) ).@count > 0 ).@count
|
||||
> 0 </string>
|
||||
<key>PHSupportedMediaTypes</key>
|
||||
<array>
|
||||
<string>Video</string>
|
||||
<string>Image</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>NSExtensionMainStoryboard</key>
|
||||
<string>MainInterface</string>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.share-services</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.com.gopeed.gopeed</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,3 @@
|
||||
import share_handler_ios_models
|
||||
|
||||
class ShareViewController: ShareHandlerIosViewController {}
|
||||
@@ -129,12 +129,20 @@ Future<void> continueTask(String id) async {
|
||||
return _parse(() => _client.dio.put("/api/v1/tasks/$id/continue"), null);
|
||||
}
|
||||
|
||||
Future<void> pauseAllTasks() async {
|
||||
return _parse(() => _client.dio.put("/api/v1/tasks/pause"), null);
|
||||
Future<void> pauseAllTasks(List<String>? ids) async {
|
||||
return _parse(
|
||||
() => _client.dio.put("/api/v1/tasks/pause", queryParameters: {
|
||||
"id": ids,
|
||||
}),
|
||||
null);
|
||||
}
|
||||
|
||||
Future<void> continueAllTasks() async {
|
||||
return _parse(() => _client.dio.put("/api/v1/tasks/continue"), null);
|
||||
Future<void> continueAllTasks(List<String>? ids) async {
|
||||
return _parse(
|
||||
() => _client.dio.put("/api/v1/tasks/continue", queryParameters: {
|
||||
"id": ids,
|
||||
}),
|
||||
null);
|
||||
}
|
||||
|
||||
Future<void> deleteTask(String id, bool force) async {
|
||||
@@ -142,6 +150,15 @@ Future<void> deleteTask(String id, bool force) async {
|
||||
() => _client.dio.delete("/api/v1/tasks/$id?force=$force"), null);
|
||||
}
|
||||
|
||||
Future<void> deleteTasks(List<String>? ids, bool force) async {
|
||||
return _parse(
|
||||
() => _client.dio.delete("/api/v1/tasks", queryParameters: {
|
||||
"id": ids,
|
||||
"force": force,
|
||||
}),
|
||||
null);
|
||||
}
|
||||
|
||||
Future<DownloaderConfig> getConfig() async {
|
||||
return _parse(() => _client.dio.get("/api/v1/config"),
|
||||
(data) => DownloaderConfig.fromJson(data));
|
||||
|
||||
@@ -80,6 +80,7 @@ class ExtraConfig {
|
||||
String locale;
|
||||
bool lastDeleteTaskKeep;
|
||||
bool defaultDirectDownload;
|
||||
bool defaultBtClient;
|
||||
|
||||
ExtraConfigBt bt = ExtraConfigBt();
|
||||
|
||||
@@ -88,6 +89,7 @@ class ExtraConfig {
|
||||
this.locale = '',
|
||||
this.lastDeleteTaskKeep = false,
|
||||
this.defaultDirectDownload = false,
|
||||
this.defaultBtClient = true,
|
||||
});
|
||||
|
||||
factory ExtraConfig.fromJson(Map<String, dynamic>? json) =>
|
||||
|
||||
@@ -73,6 +73,7 @@ ExtraConfig _$ExtraConfigFromJson(Map<String, dynamic> json) => ExtraConfig(
|
||||
locale: json['locale'] as String? ?? '',
|
||||
lastDeleteTaskKeep: json['lastDeleteTaskKeep'] as bool? ?? false,
|
||||
defaultDirectDownload: json['defaultDirectDownload'] as bool? ?? false,
|
||||
defaultBtClient: json['defaultBtClient'] as bool? ?? true,
|
||||
)..bt = ExtraConfigBt.fromJson(json['bt'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$ExtraConfigToJson(ExtraConfig instance) =>
|
||||
@@ -81,6 +82,7 @@ Map<String, dynamic> _$ExtraConfigToJson(ExtraConfig instance) =>
|
||||
'locale': instance.locale,
|
||||
'lastDeleteTaskKeep': instance.lastDeleteTaskKeep,
|
||||
'defaultDirectDownload': instance.defaultDirectDownload,
|
||||
'defaultBtClient': instance.defaultBtClient,
|
||||
'bt': instance.bt.toJson(),
|
||||
};
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ class Options {
|
||||
Object? extra;
|
||||
|
||||
Options({
|
||||
required this.name,
|
||||
required this.path,
|
||||
this.name = '',
|
||||
this.path = '',
|
||||
this.selectFiles = const [],
|
||||
this.extra,
|
||||
});
|
||||
@@ -24,12 +24,16 @@ class Options {
|
||||
|
||||
@JsonSerializable()
|
||||
class OptsExtraHttp {
|
||||
int connections = 0;
|
||||
bool autoTorrent = false;
|
||||
int connections;
|
||||
bool autoTorrent;
|
||||
|
||||
OptsExtraHttp();
|
||||
OptsExtraHttp({
|
||||
this.connections = 0,
|
||||
this.autoTorrent = false,
|
||||
});
|
||||
|
||||
factory OptsExtraHttp.fromJson(Map<String, dynamic> json) =>
|
||||
_$OptsExtraHttpFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$OptsExtraHttpToJson(this);
|
||||
}
|
||||
@@ -7,10 +7,10 @@ part of 'options.dart';
|
||||
// **************************************************************************
|
||||
|
||||
Options _$OptionsFromJson(Map<String, dynamic> json) => Options(
|
||||
name: json['name'] as String,
|
||||
path: json['path'] as String,
|
||||
name: json['name'] as String? ?? '',
|
||||
path: json['path'] as String? ?? '',
|
||||
selectFiles: (json['selectFiles'] as List<dynamic>?)
|
||||
?.map((e) => e as int)
|
||||
?.map((e) => (e as num).toInt())
|
||||
.toList() ??
|
||||
const [],
|
||||
extra: json['extra'],
|
||||
@@ -34,9 +34,10 @@ Map<String, dynamic> _$OptionsToJson(Options instance) {
|
||||
}
|
||||
|
||||
OptsExtraHttp _$OptsExtraHttpFromJson(Map<String, dynamic> json) =>
|
||||
OptsExtraHttp()
|
||||
..connections = json['connections'] as int
|
||||
..autoTorrent = json['autoTorrent'] as bool;
|
||||
OptsExtraHttp(
|
||||
connections: (json['connections'] as num?)?.toInt() ?? 0,
|
||||
autoTorrent: json['autoTorrent'] as bool? ?? false,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$OptsExtraHttpToJson(OptsExtraHttp instance) =>
|
||||
<String, dynamic>{
|
||||
|
||||
@@ -6,9 +6,9 @@ part 'request.g.dart';
|
||||
class Request {
|
||||
String url;
|
||||
Object? extra;
|
||||
Map<String, String>? labels = {};
|
||||
Map<String, String>? labels;
|
||||
RequestProxy? proxy;
|
||||
bool skipVerifyCert = false;
|
||||
bool skipVerifyCert;
|
||||
|
||||
Request({
|
||||
required this.url,
|
||||
@@ -26,11 +26,15 @@ class Request {
|
||||
|
||||
@JsonSerializable()
|
||||
class ReqExtraHttp {
|
||||
String method = 'GET';
|
||||
Map<String, String> header = {};
|
||||
String body = '';
|
||||
String method;
|
||||
Map<String, String> header;
|
||||
String body;
|
||||
|
||||
ReqExtraHttp();
|
||||
ReqExtraHttp({
|
||||
this.method = 'GET',
|
||||
this.header = const {},
|
||||
this.body = '',
|
||||
});
|
||||
|
||||
factory ReqExtraHttp.fromJson(Map<String, dynamic> json) =>
|
||||
_$ReqExtraHttpFromJson(json);
|
||||
@@ -40,9 +44,11 @@ class ReqExtraHttp {
|
||||
|
||||
@JsonSerializable()
|
||||
class ReqExtraBt {
|
||||
List<String> trackers = [];
|
||||
List<String> trackers;
|
||||
|
||||
ReqExtraBt();
|
||||
ReqExtraBt({
|
||||
this.trackers = const [],
|
||||
});
|
||||
|
||||
factory ReqExtraBt.fromJson(Map<String, dynamic> json) =>
|
||||
_$ReqExtraBtFromJson(json);
|
||||
@@ -58,15 +64,22 @@ enum RequestProxyMode {
|
||||
|
||||
@JsonSerializable()
|
||||
class RequestProxy {
|
||||
RequestProxyMode mode = RequestProxyMode.follow;
|
||||
String scheme = 'http';
|
||||
String host = '';
|
||||
String usr = '';
|
||||
String pwd = '';
|
||||
RequestProxyMode mode;
|
||||
String scheme;
|
||||
String host;
|
||||
String usr;
|
||||
String pwd;
|
||||
|
||||
RequestProxy();
|
||||
RequestProxy({
|
||||
this.mode = RequestProxyMode.follow,
|
||||
this.scheme = 'http',
|
||||
this.host = '',
|
||||
this.usr = '',
|
||||
this.pwd = '',
|
||||
});
|
||||
|
||||
factory RequestProxy.fromJson(Map<String, dynamic> json) =>
|
||||
_$RequestProxyFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$RequestProxyToJson(this);
|
||||
}
|
||||
@@ -36,10 +36,14 @@ Map<String, dynamic> _$RequestToJson(Request instance) {
|
||||
return val;
|
||||
}
|
||||
|
||||
ReqExtraHttp _$ReqExtraHttpFromJson(Map<String, dynamic> json) => ReqExtraHttp()
|
||||
..method = json['method'] as String
|
||||
..header = Map<String, String>.from(json['header'] as Map)
|
||||
..body = json['body'] as String;
|
||||
ReqExtraHttp _$ReqExtraHttpFromJson(Map<String, dynamic> json) => ReqExtraHttp(
|
||||
method: json['method'] as String? ?? 'GET',
|
||||
header: (json['header'] as Map<String, dynamic>?)?.map(
|
||||
(k, e) => MapEntry(k, e as String),
|
||||
) ??
|
||||
const {},
|
||||
body: json['body'] as String? ?? '',
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ReqExtraHttpToJson(ReqExtraHttp instance) =>
|
||||
<String, dynamic>{
|
||||
@@ -48,21 +52,26 @@ Map<String, dynamic> _$ReqExtraHttpToJson(ReqExtraHttp instance) =>
|
||||
'body': instance.body,
|
||||
};
|
||||
|
||||
ReqExtraBt _$ReqExtraBtFromJson(Map<String, dynamic> json) => ReqExtraBt()
|
||||
..trackers =
|
||||
(json['trackers'] as List<dynamic>).map((e) => e as String).toList();
|
||||
ReqExtraBt _$ReqExtraBtFromJson(Map<String, dynamic> json) => ReqExtraBt(
|
||||
trackers: (json['trackers'] as List<dynamic>?)
|
||||
?.map((e) => e as String)
|
||||
.toList() ??
|
||||
const [],
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ReqExtraBtToJson(ReqExtraBt instance) =>
|
||||
<String, dynamic>{
|
||||
'trackers': instance.trackers,
|
||||
};
|
||||
|
||||
RequestProxy _$RequestProxyFromJson(Map<String, dynamic> json) => RequestProxy()
|
||||
..mode = $enumDecode(_$RequestProxyModeEnumMap, json['mode'])
|
||||
..scheme = json['scheme'] as String
|
||||
..host = json['host'] as String
|
||||
..usr = json['usr'] as String
|
||||
..pwd = json['pwd'] as String;
|
||||
RequestProxy _$RequestProxyFromJson(Map<String, dynamic> json) => RequestProxy(
|
||||
mode: $enumDecodeNullable(_$RequestProxyModeEnumMap, json['mode']) ??
|
||||
RequestProxyMode.follow,
|
||||
scheme: json['scheme'] as String? ?? 'http',
|
||||
host: json['host'] as String? ?? '',
|
||||
usr: json['usr'] as String? ?? '',
|
||||
pwd: json['pwd'] as String? ?? '',
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$RequestProxyToJson(RequestProxy instance) =>
|
||||
<String, dynamic>{
|
||||
|
||||
@@ -11,7 +11,7 @@ Result<T> _$ResultFromJson<T>(
|
||||
T Function(Object? json) fromJsonT,
|
||||
) =>
|
||||
Result<T>(
|
||||
code: json['code'] as int,
|
||||
code: (json['code'] as num).toInt(),
|
||||
msg: json['msg'] as String?,
|
||||
data: _$nullableGenericFromJson(json['data'], fromJsonT),
|
||||
);
|
||||
|
||||
Loaded 50 of 119 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user