From 82390887c07cee6ab9da12fe4afc9b973f9ddd2b Mon Sep 17 00:00:00 2001 From: zyj <18107291228@163.com> Date: Sat, 25 Oct 2025 18:10:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=83=A8=E5=88=86=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.go | 49 ++++++++++++--- frontend/app/pages/run/pack.vue | 5 ++ frontend/app/pages/run/webpage.vue | 5 ++ frontend/bindings/go-site-clone/app.js | 25 ++++++-- .../bindings/go-site-clone/utils/index.js | 7 +++ .../bindings/go-site-clone/utils/models.js | 60 +++++++++++++++++++ frontend/bindings/time/index.js | 50 ++++++++++++++++ frontend/bindings/time/models.js | 52 ++++++++++++++++ services/site_service.go | 10 ++++ utils/file.go | 36 +++++++++++ utils/index.go | 21 +++++++ 11 files changed, 306 insertions(+), 14 deletions(-) create mode 100644 frontend/app/pages/run/pack.vue create mode 100644 frontend/app/pages/run/webpage.vue create mode 100644 frontend/bindings/go-site-clone/utils/index.js create mode 100644 frontend/bindings/go-site-clone/utils/models.js create mode 100644 frontend/bindings/time/index.js create mode 100644 frontend/bindings/time/models.js create mode 100644 utils/index.go 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 @@ + + \ 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 @@ + + \ 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 +}