新增部分功能
This commit is contained in:
39
app.go
39
app.go
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"go-site-clone/services"
|
"go-site-clone/services"
|
||||||
"go-site-clone/utils"
|
"go-site-clone/utils"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
"github.com/go-rod/rod/lib/proto"
|
"github.com/go-rod/rod/lib/proto"
|
||||||
"github.com/wailsapp/wails/v3/pkg/application"
|
"github.com/wailsapp/wails/v3/pkg/application"
|
||||||
@@ -14,6 +15,18 @@ type App struct {
|
|||||||
|
|
||||||
var siteService services.SiteService
|
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 {
|
func (a *App) GetResources(rawURL string) *services.ResourcesList {
|
||||||
RequestParamsAll, RouterAll := siteService.GetAllResources(rawURL)
|
RequestParamsAll, RouterAll := siteService.GetAllResources(rawURL)
|
||||||
// 再次去重 根据url链接去除重复项
|
// 再次去重 根据url链接去除重复项
|
||||||
@@ -36,43 +49,61 @@ func (a *App) GetResources(rawURL string) *services.ResourcesList {
|
|||||||
resources.Video = append(resources.Video, v.URL)
|
resources.Video = append(resources.Video, v.URL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return resources
|
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
|
var File utils.File
|
||||||
if len(obj.CSS) > 0 {
|
if len(obj.CSS) > 0 {
|
||||||
for k, v := range obj.CSS {
|
for k, v := range obj.CSS {
|
||||||
|
u, _ := url.Parse(v)
|
||||||
|
if parsed.Hostname() == u.Hostname() {
|
||||||
File.Download(v)
|
File.Download(v)
|
||||||
|
}
|
||||||
a.app.Event.Emit("download:css", k)
|
a.app.Event.Emit("download:css", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(obj.Script) > 0 {
|
if len(obj.Script) > 0 {
|
||||||
for k, v := range obj.Script {
|
for k, v := range obj.Script {
|
||||||
|
u, _ := url.Parse(v)
|
||||||
|
if parsed.Hostname() == u.Hostname() {
|
||||||
File.Download(v)
|
File.Download(v)
|
||||||
|
}
|
||||||
a.app.Event.Emit("download:script", k)
|
a.app.Event.Emit("download:script", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(obj.Image) > 0 {
|
if len(obj.Image) > 0 {
|
||||||
for k, v := range obj.Image {
|
for k, v := range obj.Image {
|
||||||
|
u, _ := url.Parse(v)
|
||||||
|
if parsed.Hostname() == u.Hostname() {
|
||||||
File.Download(v)
|
File.Download(v)
|
||||||
a.app.Event.Emit("download:script", k)
|
}
|
||||||
|
a.app.Event.Emit("download:image", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(obj.Video) > 0 {
|
if len(obj.Video) > 0 {
|
||||||
for k, v := range obj.Video {
|
for k, v := range obj.Video {
|
||||||
|
u, _ := url.Parse(v)
|
||||||
|
if parsed.Hostname() == u.Hostname() {
|
||||||
File.Download(v)
|
File.Download(v)
|
||||||
|
}
|
||||||
a.app.Event.Emit("download:video", k)
|
a.app.Event.Emit("download:video", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(obj.Dom) > 0 {
|
if len(obj.Dom) > 0 {
|
||||||
for k, v := range obj.Dom {
|
for k, v := range obj.Dom {
|
||||||
|
u, _ := url.Parse(v)
|
||||||
|
if parsed.Hostname() == u.Hostname() {
|
||||||
File.HTMLDownload(v)
|
File.HTMLDownload(v)
|
||||||
|
}
|
||||||
a.app.Event.Emit("download:dom", k)
|
a.app.Event.Emit("download:dom", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) GetDownloadList() []utils.FileDir {
|
||||||
|
return siteService.GetLocalSiteList()
|
||||||
|
}
|
||||||
|
|||||||
5
frontend/app/pages/run/pack.vue
Normal file
5
frontend/app/pages/run/pack.vue
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<template>
|
||||||
|
<div>1</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
5
frontend/app/pages/run/webpage.vue
Normal file
5
frontend/app/pages/run/webpage.vue
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<template>
|
||||||
|
<div>1</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
@@ -9,13 +9,26 @@ import { Call as $Call, CancellablePromise as $CancellablePromise, Create as $Cr
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import * as services$0 from "./services/models.js";
|
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
|
* @param {services$0.ResourcesList} obj
|
||||||
* @returns {$CancellablePromise<boolean>}
|
* @returns {$CancellablePromise<boolean>}
|
||||||
*/
|
*/
|
||||||
export function DownloadSite(obj) {
|
export function DownloadSite(uri, obj) {
|
||||||
return $Call.ByID(2539977978, obj);
|
return $Call.ByID(2539977978, uri, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {$CancellablePromise<utils$0.FileDir[]>}
|
||||||
|
*/
|
||||||
|
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) {
|
export function GetResources(rawURL) {
|
||||||
return $Call.ByID(2167352808, rawURL).then(/** @type {($result: any) => any} */(($result) => {
|
return $Call.ByID(2167352808, rawURL).then(/** @type {($result: any) => any} */(($result) => {
|
||||||
return $$createType1($result);
|
return $$createType3($result);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private type creation functions
|
// Private type creation functions
|
||||||
const $$createType0 = services$0.ResourcesList.createFrom;
|
const $$createType0 = utils$0.FileDir.createFrom;
|
||||||
const $$createType1 = $Create.Nullable($$createType0);
|
const $$createType1 = $Create.Array($$createType0);
|
||||||
|
const $$createType2 = services$0.ResourcesList.createFrom;
|
||||||
|
const $$createType3 = $Create.Nullable($$createType2);
|
||||||
|
|||||||
7
frontend/bindings/go-site-clone/utils/index.js
Normal file
7
frontend/bindings/go-site-clone/utils/index.js
Normal file
@@ -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";
|
||||||
60
frontend/bindings/go-site-clone/utils/models.js
Normal file
60
frontend/bindings/go-site-clone/utils/models.js
Normal file
@@ -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<FileDir>} [$$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<FileDir>} */($$parsedSource));
|
||||||
|
}
|
||||||
|
}
|
||||||
50
frontend/bindings/time/index.js
Normal file
50
frontend/bindings/time/index.js
Normal file
@@ -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
|
||||||
|
*/
|
||||||
52
frontend/bindings/time/models.js
Normal file
52
frontend/bindings/time/models.js
Normal file
@@ -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
|
||||||
|
*/
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"go-site-clone/config"
|
||||||
"go-site-clone/libs"
|
"go-site-clone/libs"
|
||||||
|
"go-site-clone/utils"
|
||||||
"log"
|
"log"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -206,3 +208,11 @@ func (s SiteService) DeduplicationRequestByUrl(list []RequestParams) []RequestPa
|
|||||||
|
|
||||||
return newList
|
return newList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取下载的网站列表
|
||||||
|
func (s SiteService) GetLocalSiteList() []utils.FileDir {
|
||||||
|
var file utils.File
|
||||||
|
appConfig, _ := config.LoadConfig()
|
||||||
|
list := file.GetFileDirList(appConfig.SiteFileDir)
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,10 +10,19 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type File struct{}
|
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 {
|
func (*File) Download(uri string) string {
|
||||||
// 解析文件链接及 路径
|
// 解析文件链接及 路径
|
||||||
u, err := url.Parse(uri)
|
u, err := url.Parse(uri)
|
||||||
@@ -54,6 +63,7 @@ func (*File) Download(uri string) string {
|
|||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建目录
|
||||||
func CreateFileWithDirs(filePath string) (*os.File, error) {
|
func CreateFileWithDirs(filePath string) (*os.File, error) {
|
||||||
// 取出目录部分
|
// 取出目录部分
|
||||||
dir := filepath.Dir(filePath)
|
dir := filepath.Dir(filePath)
|
||||||
@@ -72,6 +82,7 @@ func CreateFileWithDirs(filePath string) (*os.File, error) {
|
|||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 下载html文件到本地
|
||||||
func (*File) HTMLDownload(uri string) string {
|
func (*File) HTMLDownload(uri string) string {
|
||||||
// 解析文件链接及 路径
|
// 解析文件链接及 路径
|
||||||
u, err := url.Parse(uri)
|
u, err := url.Parse(uri)
|
||||||
@@ -115,3 +126,28 @@ func (*File) HTMLDownload(uri string) string {
|
|||||||
fmt.Println("下载完成:", fp)
|
fmt.Println("下载完成:", fp)
|
||||||
return 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
|
||||||
|
}
|
||||||
|
|||||||
21
utils/index.go
Normal file
21
utils/index.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user