diff --git a/app.go b/app.go
index 1c81b5f..914c2a2 100644
--- a/app.go
+++ b/app.go
@@ -3,6 +3,7 @@ package main
import (
"go-site-clone/services"
"go-site-clone/utils"
+ "net/url"
"github.com/go-rod/rod/lib/proto"
"github.com/wailsapp/wails/v3/pkg/application"
@@ -14,6 +15,18 @@ type App struct {
var siteService services.SiteService
+// startup is called when the app starts. The context is saved
+// so we can call the runtime methods
+// func (a *App) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
+
+// return nil
+// }
+
+// func (a *App) ServiceShutdown(ctx context.Context) error {
+
+// return nil
+// }
+
func (a *App) GetResources(rawURL string) *services.ResourcesList {
RequestParamsAll, RouterAll := siteService.GetAllResources(rawURL)
// 再次去重 根据url链接去除重复项
@@ -36,43 +49,61 @@ func (a *App) GetResources(rawURL string) *services.ResourcesList {
resources.Video = append(resources.Video, v.URL)
}
}
-
return resources
}
-func (a *App) DownloadSite(obj services.ResourcesList) bool {
+func (a *App) DownloadSite(uri string, obj services.ResourcesList) bool {
// 将页面及资源一起返回
-
+ parsed, _ := url.Parse(uri)
var File utils.File
if len(obj.CSS) > 0 {
for k, v := range obj.CSS {
- File.Download(v)
+ u, _ := url.Parse(v)
+ if parsed.Hostname() == u.Hostname() {
+ File.Download(v)
+ }
a.app.Event.Emit("download:css", k)
}
}
if len(obj.Script) > 0 {
for k, v := range obj.Script {
- File.Download(v)
+ u, _ := url.Parse(v)
+ if parsed.Hostname() == u.Hostname() {
+ File.Download(v)
+ }
a.app.Event.Emit("download:script", k)
}
}
if len(obj.Image) > 0 {
for k, v := range obj.Image {
- File.Download(v)
- a.app.Event.Emit("download:script", k)
+ u, _ := url.Parse(v)
+ if parsed.Hostname() == u.Hostname() {
+ File.Download(v)
+ }
+ a.app.Event.Emit("download:image", k)
}
}
if len(obj.Video) > 0 {
for k, v := range obj.Video {
- File.Download(v)
+ u, _ := url.Parse(v)
+ if parsed.Hostname() == u.Hostname() {
+ File.Download(v)
+ }
a.app.Event.Emit("download:video", k)
}
}
if len(obj.Dom) > 0 {
for k, v := range obj.Dom {
- File.HTMLDownload(v)
+ u, _ := url.Parse(v)
+ if parsed.Hostname() == u.Hostname() {
+ File.HTMLDownload(v)
+ }
a.app.Event.Emit("download:dom", k)
}
}
return true
}
+
+func (a *App) GetDownloadList() []utils.FileDir {
+ return siteService.GetLocalSiteList()
+}
diff --git a/frontend/app/pages/run/pack.vue b/frontend/app/pages/run/pack.vue
new file mode 100644
index 0000000..f7632d3
--- /dev/null
+++ b/frontend/app/pages/run/pack.vue
@@ -0,0 +1,5 @@
+
+ 1
+
+
\ No newline at end of file
diff --git a/frontend/app/pages/run/webpage.vue b/frontend/app/pages/run/webpage.vue
new file mode 100644
index 0000000..f7632d3
--- /dev/null
+++ b/frontend/app/pages/run/webpage.vue
@@ -0,0 +1,5 @@
+
+ 1
+
+
\ No newline at end of file
diff --git a/frontend/bindings/go-site-clone/app.js b/frontend/bindings/go-site-clone/app.js
index 5f56d18..653053e 100644
--- a/frontend/bindings/go-site-clone/app.js
+++ b/frontend/bindings/go-site-clone/app.js
@@ -9,13 +9,26 @@ import { Call as $Call, CancellablePromise as $CancellablePromise, Create as $Cr
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as services$0 from "./services/models.js";
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import * as utils$0 from "./utils/models.js";
/**
+ * @param {string} uri
* @param {services$0.ResourcesList} obj
* @returns {$CancellablePromise}
*/
-export function DownloadSite(obj) {
- return $Call.ByID(2539977978, obj);
+export function DownloadSite(uri, obj) {
+ return $Call.ByID(2539977978, uri, obj);
+}
+
+/**
+ * @returns {$CancellablePromise}
+ */
+export function GetDownloadList() {
+ return $Call.ByID(2717901443).then(/** @type {($result: any) => any} */(($result) => {
+ return $$createType1($result);
+ }));
}
/**
@@ -24,10 +37,12 @@ export function DownloadSite(obj) {
*/
export function GetResources(rawURL) {
return $Call.ByID(2167352808, rawURL).then(/** @type {($result: any) => any} */(($result) => {
- return $$createType1($result);
+ return $$createType3($result);
}));
}
// Private type creation functions
-const $$createType0 = services$0.ResourcesList.createFrom;
-const $$createType1 = $Create.Nullable($$createType0);
+const $$createType0 = utils$0.FileDir.createFrom;
+const $$createType1 = $Create.Array($$createType0);
+const $$createType2 = services$0.ResourcesList.createFrom;
+const $$createType3 = $Create.Nullable($$createType2);
diff --git a/frontend/bindings/go-site-clone/utils/index.js b/frontend/bindings/go-site-clone/utils/index.js
new file mode 100644
index 0000000..c896c03
--- /dev/null
+++ b/frontend/bindings/go-site-clone/utils/index.js
@@ -0,0 +1,7 @@
+// @ts-check
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+export {
+ FileDir
+} from "./models.js";
diff --git a/frontend/bindings/go-site-clone/utils/models.js b/frontend/bindings/go-site-clone/utils/models.js
new file mode 100644
index 0000000..c527980
--- /dev/null
+++ b/frontend/bindings/go-site-clone/utils/models.js
@@ -0,0 +1,60 @@
+// @ts-check
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import { Create as $Create } from "@wailsio/runtime";
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import * as time$0 from "../../time/models.js";
+
+export class FileDir {
+ /**
+ * Creates a new FileDir instance.
+ * @param {Partial} [$$source = {}] - The source object to create the FileDir.
+ */
+ constructor($$source = {}) {
+ if (!("name" in $$source)) {
+ /**
+ * @member
+ * @type {string}
+ */
+ this["name"] = "";
+ }
+ if (!("size" in $$source)) {
+ /**
+ * @member
+ * @type {number}
+ */
+ this["size"] = 0;
+ }
+ if (!("mode" in $$source)) {
+ /**
+ * @member
+ * @type {string}
+ */
+ this["mode"] = "";
+ }
+ if (!("modTime" in $$source)) {
+ /**
+ * @member
+ * @type {time$0.Time}
+ */
+ this["modTime"] = null;
+ }
+
+ Object.assign(this, $$source);
+ }
+
+ /**
+ * Creates a new FileDir instance from a string or object.
+ * @param {any} [$$source = {}]
+ * @returns {FileDir}
+ */
+ static createFrom($$source = {}) {
+ let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
+ return new FileDir(/** @type {Partial} */($$parsedSource));
+ }
+}
diff --git a/frontend/bindings/time/index.js b/frontend/bindings/time/index.js
new file mode 100644
index 0000000..53f5196
--- /dev/null
+++ b/frontend/bindings/time/index.js
@@ -0,0 +1,50 @@
+// @ts-check
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+import * as $models from "./models.js";
+
+/**
+ * A Time represents an instant in time with nanosecond precision.
+ *
+ * Programs using times should typically store and pass them as values,
+ * not pointers. That is, time variables and struct fields should be of
+ * type [time.Time], not *time.Time.
+ *
+ * A Time value can be used by multiple goroutines simultaneously except
+ * that the methods [Time.GobDecode], [Time.UnmarshalBinary], [Time.UnmarshalJSON] and
+ * [Time.UnmarshalText] are not concurrency-safe.
+ *
+ * Time instants can be compared using the [Time.Before], [Time.After], and [Time.Equal] methods.
+ * The [Time.Sub] method subtracts two instants, producing a [Duration].
+ * The [Time.Add] method adds a Time and a Duration, producing a Time.
+ *
+ * The zero value of type Time is January 1, year 1, 00:00:00.000000000 UTC.
+ * As this time is unlikely to come up in practice, the [Time.IsZero] method gives
+ * a simple way of detecting a time that has not been initialized explicitly.
+ *
+ * Each time has an associated [Location]. The methods [Time.Local], [Time.UTC], and Time.In return a
+ * Time with a specific Location. Changing the Location of a Time value with
+ * these methods does not change the actual instant it represents, only the time
+ * zone in which to interpret it.
+ *
+ * Representations of a Time value saved by the [Time.GobEncode], [Time.MarshalBinary], [Time.AppendBinary],
+ * [Time.MarshalJSON], [Time.MarshalText] and [Time.AppendText] methods store the [Time.Location]'s offset,
+ * but not the location name. They therefore lose information about Daylight Saving Time.
+ *
+ * In addition to the required “wall clock” reading, a Time may contain an optional
+ * reading of the current process's monotonic clock, to provide additional precision
+ * for comparison or subtraction.
+ * See the “Monotonic Clocks” section in the package documentation for details.
+ *
+ * Note that the Go == operator compares not just the time instant but also the
+ * Location and the monotonic clock reading. Therefore, Time values should not
+ * be used as map or database keys without first guaranteeing that the
+ * identical Location has been set for all values, which can be achieved
+ * through use of the UTC or Local method, and that the monotonic clock reading
+ * has been stripped by setting t = t.Round(0). In general, prefer t.Equal(u)
+ * to t == u, since t.Equal uses the most accurate comparison available and
+ * correctly handles the case when only one of its arguments has a monotonic
+ * clock reading.
+ * @typedef {$models.Time} Time
+ */
diff --git a/frontend/bindings/time/models.js b/frontend/bindings/time/models.js
new file mode 100644
index 0000000..3a116e7
--- /dev/null
+++ b/frontend/bindings/time/models.js
@@ -0,0 +1,52 @@
+// @ts-check
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import { Create as $Create } from "@wailsio/runtime";
+
+/**
+ * A Time represents an instant in time with nanosecond precision.
+ *
+ * Programs using times should typically store and pass them as values,
+ * not pointers. That is, time variables and struct fields should be of
+ * type [time.Time], not *time.Time.
+ *
+ * A Time value can be used by multiple goroutines simultaneously except
+ * that the methods [Time.GobDecode], [Time.UnmarshalBinary], [Time.UnmarshalJSON] and
+ * [Time.UnmarshalText] are not concurrency-safe.
+ *
+ * Time instants can be compared using the [Time.Before], [Time.After], and [Time.Equal] methods.
+ * The [Time.Sub] method subtracts two instants, producing a [Duration].
+ * The [Time.Add] method adds a Time and a Duration, producing a Time.
+ *
+ * The zero value of type Time is January 1, year 1, 00:00:00.000000000 UTC.
+ * As this time is unlikely to come up in practice, the [Time.IsZero] method gives
+ * a simple way of detecting a time that has not been initialized explicitly.
+ *
+ * Each time has an associated [Location]. The methods [Time.Local], [Time.UTC], and Time.In return a
+ * Time with a specific Location. Changing the Location of a Time value with
+ * these methods does not change the actual instant it represents, only the time
+ * zone in which to interpret it.
+ *
+ * Representations of a Time value saved by the [Time.GobEncode], [Time.MarshalBinary], [Time.AppendBinary],
+ * [Time.MarshalJSON], [Time.MarshalText] and [Time.AppendText] methods store the [Time.Location]'s offset,
+ * but not the location name. They therefore lose information about Daylight Saving Time.
+ *
+ * In addition to the required “wall clock” reading, a Time may contain an optional
+ * reading of the current process's monotonic clock, to provide additional precision
+ * for comparison or subtraction.
+ * See the “Monotonic Clocks” section in the package documentation for details.
+ *
+ * Note that the Go == operator compares not just the time instant but also the
+ * Location and the monotonic clock reading. Therefore, Time values should not
+ * be used as map or database keys without first guaranteeing that the
+ * identical Location has been set for all values, which can be achieved
+ * through use of the UTC or Local method, and that the monotonic clock reading
+ * has been stripped by setting t = t.Round(0). In general, prefer t.Equal(u)
+ * to t == u, since t.Equal uses the most accurate comparison available and
+ * correctly handles the case when only one of its arguments has a monotonic
+ * clock reading.
+ * @typedef {any} Time
+ */
diff --git a/services/site_service.go b/services/site_service.go
index 763ad2b..6f31a34 100644
--- a/services/site_service.go
+++ b/services/site_service.go
@@ -1,7 +1,9 @@
package services
import (
+ "go-site-clone/config"
"go-site-clone/libs"
+ "go-site-clone/utils"
"log"
"net/url"
"strings"
@@ -206,3 +208,11 @@ func (s SiteService) DeduplicationRequestByUrl(list []RequestParams) []RequestPa
return newList
}
+
+// 获取下载的网站列表
+func (s SiteService) GetLocalSiteList() []utils.FileDir {
+ var file utils.File
+ appConfig, _ := config.LoadConfig()
+ list := file.GetFileDirList(appConfig.SiteFileDir)
+ return list
+}
diff --git a/utils/file.go b/utils/file.go
index 72831d7..7bdb183 100644
--- a/utils/file.go
+++ b/utils/file.go
@@ -10,10 +10,19 @@ import (
"os"
"path"
"path/filepath"
+ "time"
)
type File struct{}
+type FileDir struct {
+ Name string `json:"name"`
+ Size int64 `json:"size"`
+ Mode string `json:"mode"`
+ ModTime time.Time `json:"modTime"`
+}
+
+// 下载文件到本地
func (*File) Download(uri string) string {
// 解析文件链接及 路径
u, err := url.Parse(uri)
@@ -54,6 +63,7 @@ func (*File) Download(uri string) string {
return fp
}
+// 创建目录
func CreateFileWithDirs(filePath string) (*os.File, error) {
// 取出目录部分
dir := filepath.Dir(filePath)
@@ -72,6 +82,7 @@ func CreateFileWithDirs(filePath string) (*os.File, error) {
return f, nil
}
+// 下载html文件到本地
func (*File) HTMLDownload(uri string) string {
// 解析文件链接及 路径
u, err := url.Parse(uri)
@@ -115,3 +126,28 @@ func (*File) HTMLDownload(uri string) string {
fmt.Println("下载完成:", fp)
return fp
}
+
+// 获取文件夹列表
+func (*File) GetFileDirList(filePath string) []FileDir {
+ var fileList []FileDir
+ entries, err := os.ReadDir(filePath)
+ if err != nil {
+ return nil
+ }
+ for _, entry := range entries {
+ if entry.IsDir() {
+ info, err := entry.Info()
+ if err != nil {
+ fmt.Println("无法获取属性:", err)
+ continue
+ }
+ fileList = append(fileList, FileDir{
+ Name: entry.Name(),
+ Size: info.Size(),
+ Mode: info.Mode().String(),
+ ModTime: info.ModTime(),
+ })
+ }
+ }
+ return fileList
+}
diff --git a/utils/index.go b/utils/index.go
new file mode 100644
index 0000000..938e77b
--- /dev/null
+++ b/utils/index.go
@@ -0,0 +1,21 @@
+package utils
+
+import (
+ "os/exec"
+)
+
+func CheckGoEnv() bool {
+ cmd := exec.Command("go", "version")
+ if err := cmd.Run(); err != nil {
+ return false
+ }
+ return true
+}
+
+func CheckWailsEnv() bool {
+ cmd := exec.Command("wails3", "version")
+ if err := cmd.Run(); err != nil {
+ return false
+ }
+ return true
+}