Skip to content

Commit ae35c32

Browse files
committed
支持导出脚本包
1 parent 3d15c7c commit ae35c32

7 files changed

Lines changed: 139 additions & 48 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
.vscode
44

55
config.yaml
6+
7+
*.zip
8+
*.exe
9+

cmd/scriptcat/exec.go

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package main
22

33
import (
4-
"io/ioutil"
4+
"archive/zip"
5+
"io"
6+
"io/fs"
7+
"os"
8+
"path"
59

610
"github.com/scriptscat/cloudcat/pkg/scriptcat"
711
"github.com/scriptscat/cloudcat/pkg/utils"
@@ -10,6 +14,7 @@ import (
1014

1115
type execCmd struct {
1216
cookiefile string
17+
runOnce bool
1318
}
1419

1520
func newExecCmd() *execCmd {
@@ -21,32 +26,72 @@ func (e *execCmd) Commands() []*cobra.Command {
2126
Use: "exec [file] [flags]",
2227
Short: "执行一个脚本猫脚本",
2328
RunE: e.exec,
29+
Args: cobra.ExactArgs(1),
2430
}
2531
ret.Flags().StringVarP(&e.cookiefile, "cookiefile", "c", "", "设置cookie文件")
32+
ret.Flags().BoolVarP(&e.runOnce, "run-once", "", false, "运行一次(如果是定时脚本的话,不会进入定时逻辑)")
2633

2734
return []*cobra.Command{ret}
2835
}
2936

3037
func (e *execCmd) exec(cmd *cobra.Command, args []string) error {
3138

32-
sc, err := scriptcat.NewScriptCat()
33-
if err != nil {
34-
return err
35-
}
36-
37-
script, err := ioutil.ReadFile(args[0])
38-
if err != nil {
39-
return err
39+
var err error
40+
var script, cookie, value fs.File
41+
if path.Ext(args[0]) == ".zip" {
42+
// 软件包
43+
pkg, err := zip.OpenReader(args[0])
44+
if err != nil {
45+
return err
46+
}
47+
script, err = pkg.Open("userScript.js")
48+
if err != nil {
49+
return err
50+
}
51+
defer script.Close()
52+
cookie, _ = pkg.Open("cookie.json")
53+
value, _ = pkg.Open("value.json")
54+
} else {
55+
script, err = os.Open(args[0])
56+
if err != nil {
57+
return err
58+
}
59+
defer script.Close()
60+
cookie, err = os.Open(e.cookiefile)
61+
if err != nil {
62+
return err
63+
}
64+
defer cookie.Close()
4065
}
4166

4267
opts := make([]scriptcat.Option, 0)
43-
if e.cookiefile != "" {
44-
jar, err := utils.ReadCookie(e.cookiefile)
68+
if cookie != nil {
69+
jar, err := utils.ReadCookie(readString(cookie))
4570
if err != nil {
4671
return err
4772
}
4873
opts = append(opts, scriptcat.WithCookie(jar))
4974
}
5075

51-
return sc.Run(string(script))
76+
if value != nil {
77+
opts = append(opts, scriptcat.WithValue(value))
78+
}
79+
80+
sc, err := scriptcat.NewScriptCat()
81+
if err != nil {
82+
return err
83+
}
84+
85+
if e.runOnce {
86+
return sc.RunOnce(readString(script), opts...)
87+
}
88+
return sc.Run(readString(script), opts...)
89+
}
90+
91+
func readString(r io.Reader) string {
92+
if r == nil {
93+
return ""
94+
}
95+
byte, _ := io.ReadAll(r)
96+
return string(byte)
5297
}

pkg/scriptcat/option.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package scriptcat
22

3-
import "net/http"
3+
import (
4+
"net/http"
5+
)
46

57
type Options struct {
68
cookieJar http.CookieJar
@@ -13,3 +15,9 @@ func WithCookie(cookie http.CookieJar) Option {
1315
opts.cookieJar = cookie
1416
}
1517
}
18+
19+
func WithValue(value interface{}) Option {
20+
return func(opts *Options) {
21+
22+
}
23+
}

pkg/scriptcat/scriptcat.go

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
package scriptcat
22

3-
import "github.com/scriptscat/cloudcat/pkg/executor"
3+
import (
4+
"errors"
5+
"sync"
6+
7+
"github.com/scriptscat/cloudcat/pkg/executor"
8+
"github.com/sirupsen/logrus"
9+
"rogchap.com/v8go"
10+
)
411

512
type ScriptCat struct {
613
script string
@@ -24,7 +31,32 @@ func (s *ScriptCat) Run(script string, opt ...Option) error {
2431
}
2532

2633
func (s *ScriptCat) RunOnce(script string, opt ...Option) error {
27-
34+
ctx, code, err := s.compile(script, opt...)
35+
if err != nil {
36+
return err
37+
}
38+
ret, err := ctx.RunScript(code, "main.js")
39+
if err != nil {
40+
return err
41+
}
42+
if !ret.IsPromise() {
43+
return errors.New("return is not a promise object")
44+
}
45+
l := sync.WaitGroup{}
46+
p, err := ret.AsPromise()
47+
if err != nil {
48+
return err
49+
}
50+
l.Add(1)
51+
p.Then(func(info *v8go.FunctionCallbackInfo) *v8go.Value {
52+
l.Done()
53+
return nil
54+
})
55+
p.Catch(func(info *v8go.FunctionCallbackInfo) *v8go.Value {
56+
l.Done()
57+
return nil
58+
})
59+
l.Wait()
2860
return nil
2961
}
3062

@@ -44,16 +76,23 @@ func (s *ScriptCat) compile(script string, opt ...Option) (*executor.Context, st
4476
return nil, "", err
4577
}
4678
// TODO: 编译code(require resource等内容)
47-
return ctx, "", nil
79+
80+
return ctx, "function main() {\n" + script + "\n}\nmain();", nil
4881
}
4982

5083
func (s *ScriptCat) buildContext(exec *executor.Executor, meta map[string][]string, opts *Options) (*executor.Context, error) {
51-
contextOpts := make([]executor.Option, 0)
84+
contextOpts := []executor.Option{
85+
executor.WithLogger(logrus.StandardLogger().Logf),
86+
executor.Console(),
87+
}
5288

5389
optMap := map[string]func() executor.Option{
5490
"GM_xmlhttpRequest": func() executor.Option {
5591
return executor.GmXmlHttpRequest(opts.cookieJar)
5692
},
93+
"GM_notification": func() executor.Option {
94+
return executor.GmNotification()
95+
},
5796
}
5897

5998
for _, v := range meta["grant"] {

pkg/scriptcat/utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ func ParseMeta(script string) string {
1010
}
1111

1212
func ParseMetaToJson(meta string) map[string][]string {
13-
reg := regexp.MustCompile("(?im)^//\\s*@(.+?)($|\\s+(.+?)$)")
13+
reg := regexp.MustCompile("(?im)^//\\s*@(.+?)([\r\n]+|$|\\s+(.+?)$)")
1414
list := reg.FindAllStringSubmatch(meta, -1)
1515
ret := make(map[string][]string)
1616
for _, v := range list {

pkg/scriptcat/utils_test.go

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package scriptcat
22

33
import (
4-
"github.com/stretchr/testify/assert"
54
"testing"
5+
6+
"github.com/stretchr/testify/assert"
67
)
78

8-
func TestParseMeta(t *testing.T) {
9-
ret := ParseMeta(`// ==UserScript==
9+
func TestParseMetaToJson(t *testing.T) {
10+
ret := ParseMetaToJson(`// ==UserScript==
1011
// @name bilibili自动签到
1112
// @namespace wyz
1213
// @version 1.1.2
@@ -17,21 +18,11 @@ func TestParseMeta(t *testing.T) {
1718
// @grant GM_notification
1819
// @connect api.bilibili.com
1920
// @connect api.live.bilibili.com
20-
// ==/UserScript==
21-
script code
22-
`)
21+
// @cloudCat
22+
// @exportCookie domain=api.bilibili.com
23+
// @exportCookie domain=api.live.bilibili.com
24+
// ==/UserScript==`)
2325

24-
assert.Equal(t, `// ==UserScript==
25-
// @name bilibili自动签到
26-
// @namespace wyz
27-
// @version 1.1.2
28-
// @author wyz
29-
// @crontab * * once * *
30-
// @debug
31-
// @grant GM_xmlhttpRequest
32-
// @grant GM_notification
33-
// @connect api.bilibili.com
34-
// @connect api.live.bilibili.com
35-
// ==/UserScript==`, ret)
26+
assert.Equal(t, 2, len(ret["grant"]))
3627

3728
}

pkg/utils/cookie.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,37 @@ package utils
22

33
import (
44
"encoding/json"
5-
"fmt"
6-
"io/ioutil"
75
"net/http"
86
"net/http/cookiejar"
97
"net/url"
8+
9+
"github.com/sirupsen/logrus"
1010
)
1111

1212
type CookieFile struct {
1313
*cookiejar.Jar
1414
}
1515

16-
func ReadCookie(filename string) (http.CookieJar, error) {
16+
func ReadCookie(cookie string) (http.CookieJar, error) {
1717
jar, _ := cookiejar.New(nil)
18-
f, err := ioutil.ReadFile(filename)
19-
if err != nil {
20-
return nil, err
21-
}
2218
m := make(map[string][]*http.Cookie)
23-
if err := json.Unmarshal(f, &m); err != nil {
19+
if err := json.Unmarshal([]byte(cookie), &m); err != nil && len(m) == 0 {
2420
return nil, err
21+
} else if err != nil {
22+
logrus.Errorf("cookie format error: %v", err)
2523
}
2624
for k, v := range m {
27-
u, err := url.Parse(k)
28-
if err != nil {
29-
return nil, fmt.Errorf("parse %s: %w", k, err)
25+
for _, v := range v {
26+
urlStr := ""
27+
if v.Secure {
28+
urlStr = "https://"
29+
} else {
30+
urlStr = "http://"
31+
}
32+
urlStr += v.Domain
33+
u, _ := url.Parse("https://" + k)
34+
jar.SetCookies(u, []*http.Cookie{v})
3035
}
31-
jar.SetCookies(u, v)
3236
}
3337
return jar, nil
3438
}

0 commit comments

Comments
 (0)