9 Commits
3.0.0 ... 3.0.2

Author SHA1 Message Date
putyy
e024a812d0 Merge pull request #124 from putyy/wails
update md
2025-01-10 17:36:10 +08:00
putyy
f5b5767997 update md 2025-01-10 17:35:39 +08:00
putyy
5e7022ec81 Merge pull request #123 from putyy/wails
Linux支持
2025-01-10 17:33:40 +08:00
putyy
e54177e8bf Linux支持 2025-01-10 17:33:05 +08:00
putyy
69cc5383d1 Merge pull request #122 from taotieren/fix-linux
Add Linux install
2025-01-09 11:30:43 +08:00
taotieren
11f88e86e3 Add Linux install 2025-01-09 11:27:07 +08:00
putyy
9e87e64223 优化 2024-12-24 14:39:13 +08:00
putyy
9ffef9db8e Delete .DS_Store 2024-12-23 17:27:38 +08:00
putyy
6d2705112d 优化 2024-12-23 16:59:26 +08:00
43 changed files with 387 additions and 283 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1,23 +1,22 @@
## res-downloader V3全新版来袭,更快了!
## res-downloader V3全新版来袭、全新实现支持更多设置视频号、直播流、m3u8预览等
### 爱享素材下载器【[加入群聊](https://qm.qq.com/q/HS8FdhpZCK)】
🎯 基于Go + [wails](https://github.com/wailsapp/wails)
📦 操作简单、可获取不同类型资源
🖥️ 支持Windows、Mac、Linux
🌐 支持视频、音频、图片、m3u8、直播流等常见网络资源
💪 支持微信视频号、小程序、抖音、快手、小红书、酷狗音乐、qq音乐等网络资源下载
👼 支持设置代理以获取特殊网络下的资源
👼 支持设置代理以获取特殊网络下的资源
## 软件下载
## 软件下载(Win7下载2.3.0版本)
🆕 [github下载](https://github.com/putyy/res-downloader/releases)
🆕 [蓝奏云下载 密码:9vs5](https://wwjv.lanzoum.com/b04wgtfyb)
## 使用方法
> 0. 安装时一定要同意安装证书文件、一定要允许网络访问
> 1. 打开本软件 软件首页左上角点击 “启动代理”
> 2. 软件首页选择要获取的资源类型(默认选中的全部)
> 3. 打开要捕获的源, 如:视频号、网页、小程序等等
> 4. 返回软件首页即可看到资源列表
> 0. 安装时一定要同意安装证书文件、一定要允许网络访问
> 1. 打开本软件 软件首页左上角点击 “启动代理”
> 2. 软件首页选择要获取的资源类型(默认选中的全部)
> 3. 打开要捕获的源, 如:视频号、网页、小程序等等
> 4. 返回软件首页即可看到资源列表
## 软件截图
![](preview/show.webp)

BIN
build/.DS_Store vendored

Binary file not shown.

View File

@@ -1,35 +1,75 @@
# Build Directory
The build directory is used to house all the build files and assets for your application.
The structure is:
* bin - Output directory
* darwin - macOS specific files
* windows - Windows specific files
## Mac
The `darwin` directory holds files specific to Mac builds.
These may be customised and used as part of the build. To return these files to the default state, simply delete them
and
build with `wails build`.
The directory contains the following files:
- `Info.plist` - the main plist file used for Mac builds. It is used when building using `wails build`.
- `Info.dev.plist` - same as the main plist file but used when building using `wails dev`.
```bash
wails build -platform "darwin/universal" --dmg-name
create-dmg 'build/bin/res-downloader.app' \
--overwrite --dmg-title="res-downloader" \
--dmg-name "res-downloader_$(jq -r '.info.productVersion' wails.json).dmg" \
./build/bin
```
## Windows
```bash
wails build -f -nsis -platform "windows/amd64" -webview2 Embed
wails build -f -nsis -platform "windows/arm64" -webview2 Embed
```
The `windows` directory contains the manifest and rc files used when building with `wails build`.
These may be customised for your application. To return these files to the default state, simply delete them and
build with `wails build`.
## Linux
- `icon.ico` - The icon used for the application. This is used when building using `wails build`. If you wish to
use a different icon, simply replace this file with your own. If it is missing, a new `icon.ico` file
will be created using the `appicon.png` file in the build directory.
- `installer/*` - The files used to create the Windows installer. These are used when building using `wails build`.
- `info.json` - Application details used for Windows builds. The data here will be used by the Windows installer,
as well as the application itself (right click the exe -> properties -> details)
- `wails.exe.manifest` - The main application manifest file.
### docker方式
> x86_64
```bash
docker build --network host -f build/linux/dockerfile -t res-downloader-amd-linux .
docker run -it --name res-downloader-amd-build --network host --privileged -v ./:/www/res-downloader res-downloader-amd-linux /bin/bash
# 容器内
cd /www/res-downloader
wails build
# 打包debian
cp build/bin/res-downloader build/linux/Debian/usr/local/bin/
echo "$(cat build/linux/Debian/DEBIAN/.control | sed -e "s/{{Version}}/$(jq -r '.info.productVersion' wails.json)/g")" > build/linux/Debian/DEBIAN/control
dpkg-deb --build ./build/linux/Debian build/bin/res-downloader_$(jq -r '.info.productVersion' wails.json)_x64.deb
# 打包AppImage
cp build/bin/res-downloader build/linux/AppImage/usr/bin/
# 复制WebKit相关文件
pushd build/linux/AppImage
find /usr/lib* -name WebKitNetworkProcess -exec mkdir -p $(dirname '{}') \; -exec cp --parents '{}' "." \; || true
find /usr/lib* -name WebKitWebProcess -exec mkdir -p $(dirname '{}') \; -exec cp --parents '{}' "." \; || true
find /usr/lib* -name libwebkit2gtkinjectedbundle.so -exec mkdir -p $(dirname '{}') \; -exec cp --parents '{}' "." \; || true
popd
wget -O ./build/bin/appimagetool-x86_64.AppImage https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage
chmod +x ./build/bin/appimagetool-x86_64.AppImage
./build/bin/appimagetool-x86_64.AppImage build/linux/AppImage build/bin/res-downloader_$(jq -r '.info.productVersion' wails.json)_x64.AppImage
```
> arm64
```bash
# arm
docker build --platform linux/arm64 --network host -f build/linux/dockerfile -t res-downloader-arm-linux .
docker run --platform linux/arm64 -it --name res-downloader-arm-build --network host --privileged -v ./:/www/res-downloader res-downloader-arm-linux /bin/bash
# 容器内
cd /www/res-downloader
wails build
# 打包debian
cp build/bin/res-downloader build/linux/Debian/usr/local/bin/
echo "$(cat build/linux/Debian/DEBIAN/.control | sed -e "s/{{Version}}/$(jq -r '.info.productVersion' wails.json)/g")" > build/linux/Debian/DEBIAN/control
dpkg-deb --build ./build/linux/Debian build/bin/res-downloader_$(jq -r '.info.productVersion' wails.json)_arm.deb
```
> ArchLinux环境
> 安装
> yay -Syu res-downloader
[![Packaging status](https://repology.org/badge/vertical-allrepos/res-downloader.svg)](https://repology.org/project/res-downloader/versions)
>
```bash
git clone https://github.com/putyy/res-downloader.git
cd res-downloader
wails build
cd build
sudo install -Dvm755 bin/res-downloader -t /usr/bin
sudo install -Dvm644 appicon.png /usr/share/icons/hicolor/512x512/apps/res-downloader.png
sudo install -Dvm644 linux/res-downloader.desktop /usr/share/applications/res-downloader.desktop
```

5
build/linux/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
!.gitkeep
debian/usr/local/bin/*
debian/DEBIAN/control
AppImage/usr/bin/*
AppImage/usr/lib/*

View File

@@ -0,0 +1 @@
res-downloader.png

View File

@@ -0,0 +1,8 @@
[Desktop Entry]
Type=Application
Name=res-downloader
Comment=This is a high-value and high-performance and diverse resource downloader called res-downloader
Exec=/usr/bin/res-downloader
Icon=/usr/share/icons/hicolor/256x256/apps/res-downloader
Terminal=false
Categories=Utility;

BIN
build/linux/AppImage/usr/.DS_Store vendored Normal file

Binary file not shown.

View File

View File

@@ -0,0 +1,8 @@
[Desktop Entry]
Type=Application
Name=res-downloader
Comment=This is a high-value and high-performance and diverse resource downloader called res-downloader
Exec=/usr/bin/res-downloader
Icon=/usr/share/icons/hicolor/256x256/apps/res-downloader
Terminal=false
Categories=Utility;

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
build/linux/Debian/.DS_Store vendored Normal file

Binary file not shown.

BIN
build/linux/Debian/DEBIAN/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,9 @@
Package: res-downloader
Version: {{Version}}
Section: utils
Priority: optional
Architecture: amd64
Depends: libwebkit2gtk-4.0-37
Maintainer: putyy@qq.com
Homepage: https://github.com/putyy/res-downloader
Description: This is a high-value and high-performance and diverse resource downloader called res-downloader

BIN
build/linux/Debian/usr/local/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,8 @@
[Desktop Entry]
Type=Application
Name=res-downloader
Comment=This is a high-value and high-performance and diverse resource downloader called res-downloader
Exec=/usr/local/bin/res-downloader
Icon=/usr/share/icons/hicolor/256x256/apps/res-downloader.png
Terminal=false
Categories=Utility;

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

29
build/linux/dockerfile Normal file
View File

@@ -0,0 +1,29 @@
FROM golang:1.23.4-bookworm
WORKDIR /
RUN apt-get update && \
apt-get install -y --fix-missing \
build-essential \
git \
jq \
kmod \
fuse \
libgtk-3-dev \
libwebkit2gtk-4.0-dev \
nsis \
wget \
curl \
gnupg2 \
lsb-release \
libfuse-dev \
libfuse2 \
file \
&& rm -rf /var/lib/apt/lists/*
RUN curl -sL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs
RUN go install github.com/wailsapp/wails/v2/cmd/wails@latest
RUN wails doctor

View File

@@ -14,7 +14,7 @@
!define INFO_PRODUCTNAME "res-downloader"
!endif
!ifndef INFO_PRODUCTVERSION
!define INFO_PRODUCTVERSION "3.0.0"
!define INFO_PRODUCTVERSION "3.0.2"
!endif
!ifndef INFO_COPYRIGHT
!define INFO_COPYRIGHT "Copyright © 2023"

View File

@@ -42,7 +42,7 @@ func GetApp(assets embed.FS) *App {
appOnce = &App{
assets: assets,
AppName: "res-downloader",
Version: "3.0.0",
Version: "3.0.2",
Description: "res-downloader是一款集网络资源嗅探 + 高速下载功能于一体的软件,高颜值、高性能和多样化,提供个人用户下载自己上传到各大平台的网络资源功能!",
Copyright: "Copyright © 2023~" + strconv.Itoa(time.Now().Year()),
PublicCrt: []byte(`
@@ -142,10 +142,12 @@ func (a *App) OnExit() {
func (a *App) installCert() {
if res, err := systemOnce.installCert(); err != nil {
if sysRuntime.GOOS == "darwin" {
DialogErr("证书安装失败,请手动执行安装命令(已复制到剪切板),err:" + err.Error() + ", " + res)
_ = runtime.ClipboardSetText(appOnce.ctx, `echo "输入本地登录密码" && sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "`+systemOnce.CertFile+`" && touch `+a.LockFile+` && echo "安装完成"`)
_ = runtime.ClipboardSetText(appOnce.ctx, `echo "输入本地登录密码" && sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "`+systemOnce.CertFile+`" && touch `+a.LockFile+` && echo "安装完成"`)
DialogErr("证书安装失败,请打开终端执行安装(命令已复制到剪切板),err:" + err.Error() + ", " + res)
} else if sysRuntime.GOOS == "windows" && strings.Contains(err.Error(), "Access is denied.") {
DialogErr("首次启用本软件,请使用鼠标右键选择以管理员身份运行")
} else if sysRuntime.GOOS == "linux" && strings.Contains(err.Error(), "Access is denied.") {
DialogErr("证书路径: " + systemOnce.CertFile + ", 请手动安装,安装完成后请执行: touch" + a.LockFile + " err:" + err.Error() + ", " + res)
} else {
globalLogger.Esg(err, res)
DialogErr("err:" + err.Error() + ", " + res)
@@ -166,7 +168,7 @@ func (a *App) OpenSystemProxy() bool {
a.IsProxy = true
return true
}
DialogErr("设置失败")
DialogErr("设置失败" + err.Error())
return false
}

View File

@@ -37,7 +37,7 @@ func initConfig() *Config {
"OpenProxy": false,
"DownloadProxy": false,
"AutoProxy": false,
"WxAction": false,
"WxAction": true,
"TaskNumber": __TaskNumber__,
"UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
}
@@ -59,6 +59,8 @@ func initConfig() *Config {
func (c *Config) setConfig(config Config) {
oldProxy := c.UpstreamProxy
c.Host = config.Host
c.Port = config.Port
c.Theme = config.Theme
c.Quality = config.Quality
c.SaveDirectory = config.SaveDirectory

View File

@@ -9,6 +9,7 @@ import (
"net/url"
"os"
"path/filepath"
"strings"
"sync"
)
@@ -68,7 +69,7 @@ func (fd *FileDownloader) init() error {
fd.Referer = parsedURL.Scheme + "://" + parsedURL.Host + "/"
}
if globalConfig.DownloadProxy && globalConfig.UpstreamProxy != "" {
if globalConfig.DownloadProxy && globalConfig.UpstreamProxy != "" && !strings.Contains(globalConfig.UpstreamProxy, globalConfig.Port) {
proxyURL, err := url.Parse(globalConfig.UpstreamProxy)
if err == nil {
fd.ProxyUrl = proxyURL

View File

@@ -1,6 +1,7 @@
package core
import (
"bytes"
"encoding/json"
"fmt"
"github.com/wailsapp/wails/v2/pkg/runtime"
@@ -20,15 +21,11 @@ type ResponseData struct {
Data interface{} `json:"data"`
}
type HttpServer struct {
broadcast chan []byte
}
type HttpServer struct{}
func initHttpServer() *HttpServer {
if httpServerOnce == nil {
httpServerOnce = &HttpServer{
broadcast: make(chan []byte),
}
httpServerOnce = &HttpServer{}
}
return httpServerOnce
}
@@ -38,9 +35,19 @@ func (h *HttpServer) run() {
if err != nil {
log.Fatalf("无法启动监听: %v", err)
}
go h.handleMessages()
fmt.Println("服务已启动,监听 http://" + globalConfig.Host + ":" + globalConfig.Port)
if err := http.Serve(listener, proxyOnce.Proxy); err != nil {
if err := http.Serve(listener, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Host == "127.0.0.1:"+globalConfig.Port && strings.Contains(r.URL.Path, "/cert") {
w.Header().Set("Content-Type", "application/x-x509-ca-data")
w.Header().Set("Content-Disposition", "attachment;filename=res-downloader-public.crt")
w.Header().Set("Content-Transfer-Encoding", "binary")
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(appOnce.PublicCrt)))
w.WriteHeader(http.StatusOK)
_, err = io.Copy(w, io.NopCloser(bytes.NewReader(appOnce.PublicCrt)))
} else {
proxyOnce.Proxy.ServeHTTP(w, r) // 代理
}
})); err != nil {
fmt.Printf("服务器异常: %v", err)
}
}
@@ -90,13 +97,6 @@ func (h *HttpServer) preview(w http.ResponseWriter, r *http.Request) {
return
}
func (h *HttpServer) handleMessages() {
for {
msg := <-h.broadcast
runtime.EventsEmit(appOnce.ctx, "event", string(msg))
}
}
func (h *HttpServer) send(t string, data interface{}) {
jsonData, err := json.Marshal(map[string]interface{}{
"type": t,
@@ -106,7 +106,7 @@ func (h *HttpServer) send(t string, data interface{}) {
fmt.Println("Error converting map to JSON:", err)
return
}
h.broadcast <- jsonData
runtime.EventsEmit(appOnce.ctx, "event", string(jsonData))
}
func (h *HttpServer) writeJson(w http.ResponseWriter, data ResponseData) {
@@ -179,13 +179,13 @@ func (h *HttpServer) openFolder(w http.ResponseWriter, r *http.Request) {
case "linux":
// linux
// 尝试使用不同的文件管理器
cmd = exec.Command("nautilus", filePath) // 尝试Nautilus
cmd = exec.Command("nautilus", filePath)
if err := cmd.Start(); err != nil {
cmd = exec.Command("thunar", filePath) // 尝试Thunar
cmd = exec.Command("thunar", filePath)
if err := cmd.Start(); err != nil {
cmd = exec.Command("dolphin", filePath) // 尝试Dolphin
cmd = exec.Command("dolphin", filePath)
if err := cmd.Start(); err != nil {
cmd = exec.Command("pcmanfm", filePath) // 尝试PCManFM
cmd = exec.Command("pcmanfm", filePath)
if err := cmd.Start(); err != nil {
globalLogger.err(err)
h.writeJson(w, ResponseData{Code: 0, Message: err.Error()})

View File

@@ -15,14 +15,14 @@ func Middleware(next http.Handler) http.Handler {
}
func HandleApi(w http.ResponseWriter, r *http.Request) bool {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusNoContent)
return true
}
if strings.HasPrefix(r.URL.Path, "/api") {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusNoContent)
return true
}
switch r.URL.Path {
case "/api/preview":
httpServerOnce.preview(w, r)

View File

@@ -95,7 +95,7 @@ func (p *Proxy) setTransport() {
IdleConnTimeout: 30 * time.Second,
}
if globalConfig.UpstreamProxy != "" && globalConfig.OpenProxy {
if globalConfig.UpstreamProxy != "" && globalConfig.OpenProxy && !strings.Contains(globalConfig.UpstreamProxy, globalConfig.Port) {
proxyURL, err := url.Parse(globalConfig.UpstreamProxy)
if err == nil {
transport.Proxy = http.ProxyURL(proxyURL)
@@ -105,40 +105,18 @@ func (p *Proxy) setTransport() {
}
func (p *Proxy) httpRequestEvent(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
if strings.Contains(r.Host, "res-downloader.666666.com") {
if strings.Contains(r.URL.Path, "/wechat") {
if globalConfig.WxAction && r.URL.Query().Get("type") == "1" {
return p.handleWechatRequest(r, ctx)
} else if !globalConfig.WxAction && r.URL.Query().Get("type") == "2" {
return p.handleWechatRequest(r, ctx)
} else {
return r, p.buildEmptyResponse(r)
}
}
if strings.Contains(r.URL.Path, "/cert") {
return p.handleCertRequest(r, ctx)
if strings.Contains(r.Host, "res-downloader.666666.com") && strings.Contains(r.URL.Path, "/wechat") {
if globalConfig.WxAction && r.URL.Query().Get("type") == "1" {
return p.handleWechatRequest(r, ctx)
} else if !globalConfig.WxAction && r.URL.Query().Get("type") == "2" {
return p.handleWechatRequest(r, ctx)
} else {
return r, p.buildEmptyResponse(r)
}
}
return r, nil
}
func (p *Proxy) handleCertRequest(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
resp := &http.Response{
StatusCode: http.StatusOK,
ProtoMajor: 1,
ProtoMinor: 1,
Header: http.Header{
"Content-Type": []string{"application/x-x509-ca-data"},
"Content-Disposition": []string{"attachment;filename=z-der-data.crt"},
"Content-Transfer-Encoding": []string{"binary"},
},
Body: io.NopCloser(bytes.NewReader(appOnce.PublicCrt)),
Request: r,
}
return r, resp
}
func (p *Proxy) handleWechatRequest(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
body, err := io.ReadAll(r.Body)
if err != nil {

View File

@@ -5,94 +5,88 @@ package core
import (
"bytes"
"fmt"
"log"
"net"
"os/exec"
"strings"
)
func (s *SystemSetup) getActiveInterface() (string, error) {
interfaces, err := net.Interfaces()
func (s *SystemSetup) getNetworkServices() ([]string, error) {
cmd := exec.Command("networksetup", "-listallnetworkservices")
output, err := cmd.Output()
if err != nil {
return "", err
return nil, fmt.Errorf("failed to execute command: %v", err)
}
for _, inter := range interfaces {
if inter.Flags&net.FlagUp != 0 && inter.Flags&net.FlagLoopback == 0 {
return inter.Name, nil
}
}
return "", fmt.Errorf("no active network interface found")
}
services := strings.Split(string(output), "\n")
func (s *SystemSetup) getNetworkServiceName(interfaceName string) (string, error) {
cmd := exec.Command("networksetup", "-listallhardwareports")
var out bytes.Buffer
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
return "", err
var validServices []string
for _, service := range services {
service = strings.TrimSpace(service)
if service != "" && !strings.Contains(service, "*") && !strings.Contains(service, "Serial Port") {
validServices = append(validServices, service)
}
}
output := out.String()
lines := strings.Split(output, "\n")
var serviceName string
for _, line := range lines {
if strings.Contains(line, "Hardware Port:") {
serviceName = strings.TrimSpace(strings.Split(line, ":")[1])
}
if strings.Contains(line, "Device: "+interfaceName) {
return serviceName, nil
}
}
return "", fmt.Errorf("no matching network service found for interface %s", interfaceName)
return validServices, nil
}
func (s *SystemSetup) setProxy() error {
interfaceName, err := s.getActiveInterface()
services, err := s.getNetworkServices()
if err != nil {
return err
}
serviceName, err := s.getNetworkServiceName(interfaceName)
if err != nil {
return err
}
commands := [][]string{
{"networksetup", "-setwebproxy", serviceName, "127.0.0.1", globalConfig.Port},
{"networksetup", "-setsecurewebproxy", serviceName, "127.0.0.1", globalConfig.Port},
if len(services) == 0 {
return fmt.Errorf("find to Network failed")
}
for _, cmd := range commands {
if err := exec.Command(cmd[0], cmd[1:]...).Run(); err != nil {
return err
is := false
for _, serviceName := range services {
if err := exec.Command("networksetup", "-setwebproxy", serviceName, "127.0.0.1", globalConfig.Port).Run(); err != nil {
fmt.Println(err)
} else {
is = true
}
if err := exec.Command("networksetup", "-setsecurewebproxy", serviceName, "127.0.0.1", globalConfig.Port).Run(); err != nil {
fmt.Println(err)
} else {
is = true
}
}
return nil
if is {
return nil
}
return fmt.Errorf("find to Network failed")
}
func (s *SystemSetup) unsetProxy() error {
interfaceName, err := s.getActiveInterface()
services, err := s.getNetworkServices()
if err != nil {
return err
}
serviceName, err := s.getNetworkServiceName(interfaceName)
if err != nil {
return err
}
commands := [][]string{
{"networksetup", "-setwebproxystate", serviceName, "off"},
{"networksetup", "-setsecurewebproxystate", serviceName, "off"},
if len(services) == 0 {
return fmt.Errorf("find to Network failed")
}
for _, cmd := range commands {
if err := exec.Command(cmd[0], cmd[1:]...).Run(); err != nil {
log.Println("UnsetProxy failed:", err)
return err
is := false
for _, serviceName := range services {
if err := exec.Command("networksetup", "-setwebproxystate", serviceName, "off").Run(); err != nil {
fmt.Println(err)
} else {
is = true
}
if err := exec.Command("networksetup", "-setsecurewebproxystate", serviceName, "off").Run(); err != nil {
fmt.Println(err)
} else {
is = true
}
}
return nil
if is {
return nil
}
return fmt.Errorf("find to Network failed")
}
func (s *SystemSetup) installCert() (string, error) {
@@ -101,7 +95,7 @@ func (s *SystemSetup) installCert() (string, error) {
return "", err
}
getPasswordCmd := exec.Command("osascript", "-e", `tell app "System Events" to display dialog "请输入密码,用于安装证书:" default answer "" with hidden answer`, "-e", `text returned of result`)
getPasswordCmd := exec.Command("osascript", "-e", `tell app "System Events" to display dialog "请输入你的电脑密码,用于安装证书文件:" default answer "" with hidden answer`, "-e", `text returned of result`)
passwordOutput, err := getPasswordCmd.Output()
if err != nil {
return string(passwordOutput), err

View File

@@ -3,7 +3,7 @@
package core
import (
"os"
"fmt"
"os/exec"
)
@@ -15,13 +15,18 @@ func (s *SystemSetup) setProxy() error {
{"gsettings", "set", "org.gnome.system.proxy.https", "host", "127.0.0.1"},
{"gsettings", "set", "org.gnome.system.proxy.https", "port", globalConfig.Port},
}
is := false
for _, cmd := range commands {
if err := exec.Command(cmd[0], cmd[1:]...).Run(); err != nil {
return err
fmt.Println(err)
} else {
is = true
}
}
return nil
if is {
return nil
}
return fmt.Errorf("Failed to activate proxy")
}
func (s *SystemSetup) unsetProxy() error {
@@ -30,21 +35,40 @@ func (s *SystemSetup) unsetProxy() error {
}
func (s *SystemSetup) installCert() (string, error) {
certData, err := s.initCert()
if err != nil {
return "", err
}
destFile := "/usr/local/share/ca-certificates/" + appOnce.AppName + ".crt"
err = os.WriteFile(destFile, certData, 0644)
_, err := s.initCert()
if err != nil {
return "", err
}
cmd := exec.Command("sudo", "update-ca-certificates")
output, err := cmd.CombinedOutput()
if err != nil {
return string(output), err
actions := [][]string{
{"/usr/local/share/ca-certificates/", "update-ca-certificates"},
{"/usr/share/ca-certificates/trust-source/anchors/", "update-ca-trust"},
{"/usr/share/ca-certificates/trust-source/anchors/", "trust extract-compat"},
{"/etc/pki/ca-trust/source/anchors/", "update-ca-trust"},
{"/etc/ssl/ca-certificates/", "update-ca-certificates"},
}
is := false
for _, action := range actions {
dir := action[0]
if err := exec.Command("sudo", "cp", "-f", s.CertFile, dir+appOnce.AppName+".crt").Run(); err != nil {
fmt.Printf("Failed to copy to %s: %v\n", dir, err)
continue
}
cmd := action[1]
if err := exec.Command("sudo", cmd).Run(); err != nil {
fmt.Printf("Failed to refresh certificates using %s: %v\n", cmd, err)
continue
}
is = true
}
if !is {
return "", fmt.Errorf("Certificate installation failed")
}
return "", nil
}

View File

@@ -4,6 +4,7 @@ import (
"crypto/md5"
"encoding/hex"
"fmt"
"github.com/wailsapp/wails/v2/pkg/runtime"
"net/url"
"os"
"strings"
@@ -14,9 +15,11 @@ func Empty(data interface{}) {
}
func DialogErr(message string) {
httpServerOnce.send("message", map[string]interface{}{
"code": 0,
"message": message,
_, _ = runtime.MessageDialog(appOnce.ctx, runtime.MessageDialogOptions{
Type: runtime.ErrorDialog,
Title: "Error",
Message: message,
DefaultButton: "Cancel",
})
}

View File

@@ -12,9 +12,9 @@
import NaiveProvider from '@/components/NaiveProvider.vue'
import {darkTheme, lightTheme, zhCN} from 'naive-ui'
import {useIndexStore} from "@/stores"
import {computed, onMounted, watch} from "vue"
import type {wsType} from "@/types/ws"
import {computed, onMounted} from "vue"
import {useEventStore} from "@/stores/event"
import {appType} from "@/types/app";
const store = useIndexStore()
const eventStore = useEventStore()
@@ -33,7 +33,7 @@ onMounted(async () => {
eventStore.init()
eventStore.addHandle({
type: "message",
event: (res: wsType.Message)=>{
event: (res: appType.Message)=>{
switch (res?.code) {
case 0:
window?.$message?.error(res.message)

View File

@@ -47,6 +47,7 @@
<div>{{ store.appInfo.Copyright }}</div>
<div class="flex">
<button class="pl-4" @click="toWebsite('https://s.gowas.cn/d/4089')">论坛</button>
<button class="pl-4" @click="toWebsite('http://127.0.0.1:8899/cert')">证书</button>
<button class="pl-4" @click="toWebsite('https://github.com/putyy/res-downloader')">软件源码</button>
<button class="pl-4" @click="toWebsite('https://github.com/putyy/res-downloader/issues')">帮助支持</button>
<button class="pl-4" @click="toWebsite('https://github.com/putyy/res-downloader/releases')">更新日志</button>
@@ -58,7 +59,7 @@
<script lang="ts" setup>
import {useIndexStore} from "@/stores"
import {BrowserOpenURL} from "../../wailsjs/runtime";
import {BrowserOpenURL} from "../../wailsjs/runtime"
const store = useIndexStore()
const props = defineProps(["showModal"])
const emits = defineEmits(["update:showModal"])

View File

@@ -35,7 +35,6 @@ const minimizeWindow = () => {
WindowMinimise()
}
const maximizeWindow = () => {
console.log("maximizeWindow")
isMaximized.value = !isMaximized.value;
if (isMaximized.value) {
WindowFullscreen()

View File

@@ -47,7 +47,7 @@
</template>
<script lang="ts" setup>
import type {MenuOption} from "naive-ui"
import {MenuOption} from "naive-ui"
import {NIcon} from "naive-ui"
import {computed, h, ref, watch} from "vue"
import {useRoute, useRouter} from "vue-router"
@@ -55,11 +55,12 @@ import {
CloudOutline,
SettingsOutline,
HelpCircleOutline,
MoonOutline
MoonOutline, SunnyOutline, LogoGithub
} from "@vicons/ionicons5"
import {useIndexStore} from "@/stores"
import Footer from "@/components/Footer.vue"
import Screen from "@/components/Screen.vue";
import {BrowserOpenURL} from "../../../wailsjs/runtime";
const route = useRoute()
const router = useRouter()
@@ -75,6 +76,10 @@ const globalConfig = computed(()=>{
return store.globalConfig
})
const theme = computed(() => {
return store.globalConfig.Theme === "darkTheme" ? renderIcon(SunnyOutline) : renderIcon(MoonOutline)
})
watch(() => route.path, (newPath, oldPath) => {
menuValue.value = route.fullPath.substring(1)
});
@@ -100,7 +105,12 @@ const footerOptions = ref([
{
label: "主题",
key: 'theme',
icon: renderIcon(MoonOutline),
icon: theme,
},
{
label: "github",
key: 'github',
icon: renderIcon(LogoGithub),
},
{
label: "关于",
@@ -118,6 +128,11 @@ const handleFooterUpdate = (key: string, item: MenuOption) => {
showAppInfo.value = true
return
}
if (key === "github") {
BrowserOpenURL("https://github.com/putyy/res-downloader")
return
}
if (key === "theme") {
if (globalConfig.value.Theme === "darkTheme") {
store.setConfig(Object.assign({}, globalConfig.value, {Theme: "lightTheme"}))

View File

@@ -1,8 +1,6 @@
export const DwStatus = {
ready: "就绪",
running: "运行中",
pause: "暂停",
wait: "等待",
error: "错误",
done: "完成",
handle: "已下载,后续处理",

View File

@@ -1,7 +1,7 @@
import {defineStore} from "pinia"
import {ref} from "vue"
import type {wsType} from "@/types/ws"
import {EventsOn} from "../../wailsjs/runtime"
import {appType} from "@/types/app"
export const useEventStore = defineStore('ws-store', () => {
const handles = ref<any>({})
@@ -17,7 +17,7 @@ export const useEventStore = defineStore('ws-store', () => {
})
}
const addHandle = (handle: wsType.Handle) => {
const addHandle = (handle: appType.Handle) => {
handles.value[handle.type] = handle.event
}

View File

@@ -2,7 +2,7 @@ import {defineStore} from 'pinia'
import {ref} from "vue"
import type {appType} from "@/types/app"
import appApi from "@/api/app"
import {Environment} from "../../wailsjs/runtime";
import {Environment} from "../../wailsjs/runtime"
export const useIndexStore = defineStore("index-store", () => {
const appInfo = ref<appType.App>({

View File

@@ -44,4 +44,14 @@ export namespace appType {
Status: string
Message: string
}
interface Message {
code: number
message: string
}
interface Handle {
type: string
event: any
}
}

View File

@@ -1,21 +0,0 @@
export namespace wsType {
interface Event {
type: string
event: any
data: any
}
interface Handle {
type: string
event: any
}
interface Message {
code: number
message: string
}
interface Clipboard {
content: string
}
}

View File

@@ -40,10 +40,10 @@ import ShowLoading from "@/components/ShowLoading.vue"
import {getDecryptionArray} from '@/assets/js/decrypt.js'
import {useIndexStore} from "@/stores"
import appApi from "@/api/app"
import {DwStatus} from "@/const";
import {DwStatus} from "@/const"
import ResAction from "@/components/ResAction.vue"
import {useEventStore} from "@/stores/event";
import {BrowserOpenURL, ClipboardSetText} from "../../wailsjs/runtime";
import {useEventStore} from "@/stores/event"
import {BrowserOpenURL, ClipboardSetText} from "../../wailsjs/runtime"
const eventStore = useEventStore()

View File

@@ -85,7 +85,7 @@
<span>可结合其他代理工具用于访问国外网站以及正常网络无法访问的资源(格式http://username:password@your.proxy.server:port)</span>
</NTooltip>
</NFormItem>
<NFormItem label="开启上游代理" path="OpenProxy" size="small">
<NFormItem label="开启代理" path="OpenProxy" size="small">
<NSwitch v-model:value="formValue.OpenProxy" />
</NFormItem>
<NFormItem label="下载代理" path="DownloadProxy" size="small">
@@ -101,6 +101,14 @@
</NFormItem>
<NFormItem label="连接数" path="TaskNumber" size="small">
<NInputNumber v-model:value="formValue.TaskNumber" :min="2" :max="64" class="w-64"/>
<NTooltip trigger="hover">
<template #trigger>
<NIcon size="20" class="pl-1">
<HelpCircleOutline />
</NIcon>
</template>
<span>如不清楚请保持默认通常CPU核心数*2用于分片下载</span>
</NTooltip>
</NFormItem>
<NFormItem label="UserAgent" path="UserAgent" size="small">
<NInput v-model:value="formValue.UserAgent" style="width:256px" placeholder=""/>

33
go.mod
View File

@@ -1,11 +1,11 @@
module res-downloader
go 1.21
go 1.22.0
toolchain go1.23.2
require (
github.com/elazarl/goproxy v0.0.0-20241221210044-9faedc2f9e9f
github.com/elazarl/goproxy v0.0.0-20241223171911-d5978cb8c956
github.com/matoous/go-nanoid/v2 v2.1.0
github.com/rs/zerolog v1.33.0
github.com/vrischmann/userdir v0.0.0-20151206171402-20f291cebd68
@@ -15,31 +15,28 @@ require (
require (
github.com/bep/debounce v1.2.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
github.com/labstack/echo/v4 v4.10.2 // indirect
github.com/labstack/gommon v0.4.0 // indirect
github.com/leaanthony/go-ansi-parser v1.6.0 // indirect
github.com/leaanthony/gosod v1.0.3 // indirect
github.com/labstack/echo/v4 v4.13.3 // indirect
github.com/labstack/gommon v0.4.2 // indirect
github.com/leaanthony/go-ansi-parser v1.6.1 // indirect
github.com/leaanthony/gosod v1.0.4 // indirect
github.com/leaanthony/slicer v1.6.0 // indirect
github.com/leaanthony/u v1.1.0 // indirect
github.com/leaanthony/u v1.1.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/samber/lo v1.38.1 // indirect
github.com/tkrajina/go-reflector v0.5.6 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/samber/lo v1.47.0 // indirect
github.com/tkrajina/go-reflector v0.5.8 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/wailsapp/go-webview2 v1.0.16 // indirect
github.com/wailsapp/go-webview2 v1.0.18 // indirect
github.com/wailsapp/mimetype v1.4.1 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/text v0.21.0 // indirect
)
// replace github.com/wailsapp/wails/v2 v2.9.2 => /Users/wgc/go/pkg/mod

80
go.sum
View File

@@ -1,95 +1,84 @@
github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/elazarl/goproxy v0.0.0-20241221210044-9faedc2f9e9f h1:88OAVe185Z0YRj/KtiYdFxrEfGBlWBd6cspLJJvgMKo=
github.com/elazarl/goproxy v0.0.0-20241221210044-9faedc2f9e9f/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64=
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/elazarl/goproxy v0.0.0-20241223171911-d5978cb8c956 h1:HyPt0ZkHkpke+HFl/4dDMz55A/AjFn7ZnLSm8GfdnwU=
github.com/elazarl/goproxy v0.0.0-20241223171911-d5978cb8c956/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc=
github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA=
github.com/leaanthony/go-ansi-parser v1.6.0 h1:T8TuMhFB6TUMIUm0oRrSbgJudTFw9csT3ZK09w0t4Pg=
github.com/leaanthony/go-ansi-parser v1.6.0/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU=
github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ=
github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRCSG7jGxs4=
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
github.com/leaanthony/go-ansi-parser v1.6.1 h1:xd8bzARK3dErqkPFtoF9F3/HgN8UQk0ed1YDKpEz01A=
github.com/leaanthony/go-ansi-parser v1.6.1/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU=
github.com/leaanthony/gosod v1.0.4 h1:YLAbVyd591MRffDgxUOU1NwLhT9T1/YiwjKZpkNFeaI=
github.com/leaanthony/gosod v1.0.4/go.mod h1:GKuIL0zzPj3O1SdWQOdgURSuhkF+Urizzxh26t9f1cw=
github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/Js=
github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8=
github.com/leaanthony/u v1.1.0 h1:2n0d2BwPVXSUq5yhe8lJPHdxevE2qK5G99PMStMZMaI=
github.com/leaanthony/u v1.1.0/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI=
github.com/leaanthony/u v1.1.1 h1:TUFjwDGlNX+WuwVEzDqQwC2lOv0P4uhTQw7CMFdiK7M=
github.com/leaanthony/u v1.1.1/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI=
github.com/matoous/go-nanoid/v2 v2.1.0 h1:P64+dmq21hhWdtvZfEAofnvJULaRR1Yib0+PnU669bE=
github.com/matoous/go-nanoid/v2 v2.1.0/go.mod h1:KlbGNQ+FhrUNIHUxZdL63t7tl4LaPkZNpUULS8H4uVM=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
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/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/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tkrajina/go-reflector v0.5.6 h1:hKQ0gyocG7vgMD2M3dRlYN6WBBOmdoOzJ6njQSepKdE=
github.com/tkrajina/go-reflector v0.5.6/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4=
github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc=
github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tkrajina/go-reflector v0.5.8 h1:yPADHrwmUbMq4RGEyaOUpz2H90sRsETNVpjzo3DLVQQ=
github.com/tkrajina/go-reflector v0.5.8/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/vrischmann/userdir v0.0.0-20151206171402-20f291cebd68 h1:Ah2/69Z24rwD6OByyOdpJDmttftz0FTF8Q4QZ/SF1E4=
github.com/vrischmann/userdir v0.0.0-20151206171402-20f291cebd68/go.mod h1:EqKqAeKddSL9XSGnfXd/7iLncccKhR16HBKVva7ENw8=
github.com/wailsapp/go-webview2 v1.0.16 h1:wffnvnkkLvhRex/aOrA3R7FP7rkvOqL/bir1br7BekU=
github.com/wailsapp/go-webview2 v1.0.16/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo=
github.com/wailsapp/go-webview2 v1.0.18 h1:SSSCoLA+MYikSp1U0WmvELF/4c3x5kH8Vi31TKyZ4yk=
github.com/wailsapp/go-webview2 v1.0.18/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc=
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
github.com/wailsapp/wails/v2 v2.9.2 h1:Xb5YRTos1w5N7DTMyYegWaGukCP2fIaX9WF21kPPF2k=
github.com/wailsapp/wails/v2 v2.9.2/go.mod h1:uehvlCwJSFcBq7rMCGfk4rxca67QQGsbg5Nm4m9UnBs=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
@@ -99,8 +88,5 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -13,7 +13,7 @@
"info": {
"companyName": "res-downloader",
"productName": "res-downloader",
"productVersion": "3.0.0",
"productVersion": "3.0.2",
"copyright": "Copyright © 2023",
"comments": "This is a high-value, high-performance, and diverse resource downloader called res-downloader."
}