Skip to content

Commit 140b2bb

Browse files
committed
v0.8.0
- 优化gpython类型转换方法
1 parent aa286bf commit 140b2bb

File tree

6 files changed

+181
-123
lines changed

6 files changed

+181
-123
lines changed

internal/plugin/python/lib/core.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ import (
99
"github.com/wetor/AnimeGo/internal/animego/feed/rss"
1010
"github.com/wetor/AnimeGo/internal/models"
1111
"github.com/wetor/AnimeGo/pkg/json"
12-
"github.com/wetor/AnimeGo/pkg/plugin"
12+
"github.com/wetor/AnimeGo/pkg/plugin/python"
1313
"github.com/wetor/AnimeGo/pkg/try"
14-
"github.com/wetor/AnimeGo/pkg/utils"
1514
)
1615

1716
func InitAnimeGo() {
@@ -70,7 +69,7 @@ func loads(self py.Object, args py.Tuple) (py.Object, error) {
7069
if err != nil {
7170
return nil, err
7271
}
73-
return plugin.Value2PyObject(result), nil
72+
return python.ToObject(result), nil
7473
}
7574

7675
func dumps(self py.Object, args py.Tuple) (py.Object, error) {
@@ -86,7 +85,7 @@ func dumps(self py.Object, args py.Tuple) (py.Object, error) {
8685
encodng = string(args[1].(py.String))
8786
}
8887

89-
object := plugin.PyObject2Value(obj)
88+
object := python.ToValue(obj)
9089
var result []byte
9190
var err error
9291

@@ -101,7 +100,7 @@ func dumps(self py.Object, args py.Tuple) (py.Object, error) {
101100
if err != nil {
102101
return nil, err
103102
}
104-
return plugin.Value2PyObject(string(result)), nil
103+
return python.ToObject(string(result)), nil
105104
}
106105

107106
func parseMikan(self py.Object, arg py.Object) (py.Object, error) {
@@ -115,9 +114,8 @@ func parseMikan(self py.Object, arg py.Object) (py.Object, error) {
115114
if err != nil {
116115
return nil, err
117116
}
118-
obj := map[string]any(utils.StructToMap(info))
119117

120-
return plugin.Value2PyObject(obj), nil
118+
return python.ToObject(info), nil
121119
}
122120

123121
func parseMikanRss(self py.Object, arg py.Object) (py.Object, error) {
@@ -131,5 +129,5 @@ func parseMikanRss(self py.Object, arg py.Object) (py.Object, error) {
131129
if err != nil {
132130
return nil, err
133131
}
134-
return plugin.Value2PyObject(items), nil
132+
return python.ToObject(items), nil
135133
}

internal/plugin/python/lib/log.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package lib
33
import (
44
"github.com/go-python/gpython/py"
55
log2 "github.com/wetor/AnimeGo/pkg/log"
6-
"github.com/wetor/AnimeGo/pkg/plugin"
6+
"github.com/wetor/AnimeGo/pkg/plugin/python"
77
)
88

99
func InitLog() {
@@ -53,10 +53,10 @@ func log(name string) func(self py.Object, args py.Tuple) (py.Object, error) {
5353
if len(args) < 1 {
5454
return py.AttributeError, nil
5555
}
56-
f := plugin.PyObject2Value(args[0]).(string)
56+
f := python.ToValue(args[0]).(string)
5757
list := make([]any, len(args)-1)
5858
for i := 0; i < len(args)-1; i++ {
59-
list[i] = plugin.PyObject2Value(args[i+1])
59+
list[i] = python.ToValue(args[i+1])
6060
}
6161
logFuncf(f, list...)
6262

@@ -66,7 +66,7 @@ func log(name string) func(self py.Object, args py.Tuple) (py.Object, error) {
6666
return func(self py.Object, args py.Tuple) (py.Object, error) {
6767
list := make([]any, len(args))
6868
for i := 0; i < len(args); i++ {
69-
list[i] = plugin.PyObject2Value(args[i])
69+
list[i] = python.ToValue(args[i])
7070
}
7171
logFunc(list...)
7272

pkg/plugin/python/python.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ import (
1717
"github.com/wetor/AnimeGo/pkg/xpath"
1818
)
1919

20-
const Type = "python"
21-
2220
type Python struct {
2321
functions map[string]*Function
2422
variables map[string]*Variable
@@ -83,12 +81,12 @@ func (p *Python) execute() {
8381
func (p *Python) endExecute() {
8482
for name, function := range p.functions {
8583
function.Func = func(args map[string]any) map[string]any {
86-
pyObj := plugin.Value2PyObject(args)
84+
pyObj := ToObject(args)
8785
res, err := p.module.Call(name, py.Tuple{pyObj}, nil)
8886
if err != nil {
8987
py.TracebackDump(err)
9088
}
91-
obj, ok := plugin.PyObject2Value(res).(map[string]any)
89+
obj, ok := ToValue(res).(map[string]any)
9290
if !ok {
9391
obj = map[string]any{
9492
"result": obj,
@@ -133,7 +131,7 @@ func (p *Python) endExecute() {
133131
return nil, err
134132
}
135133
}
136-
return plugin.Value2PyObject(result), nil
134+
return ToObject(result), nil
137135
}, 0, `_get_config() -> dict`))
138136

139137
}
@@ -145,7 +143,7 @@ func (p *Python) endExecute() {
145143
// @param name
146144
// @return any
147145
func (p *Python) Get(name string) any {
148-
return plugin.PyObject2Value(p.module.Globals[name])
146+
return ToValue(p.module.Globals[name])
149147
}
150148

151149
// Set
@@ -155,7 +153,11 @@ func (p *Python) Get(name string) any {
155153
// @param name
156154
// @param val
157155
func (p *Python) Set(name string, val any) {
158-
p.module.Globals[name] = plugin.Value2PyObject(val)
156+
if m, ok := val.(*py.Method); ok {
157+
p.module.Globals[name] = m
158+
} else {
159+
p.module.Globals[name] = ToObject(val)
160+
}
159161
}
160162

161163
// Type

pkg/plugin/python/utils.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package python
2+
3+
import (
4+
"reflect"
5+
6+
"github.com/go-python/gpython/py"
7+
8+
"github.com/wetor/AnimeGo/pkg/errors"
9+
)
10+
11+
func StructToObject(src any) py.Object {
12+
tempSrcValue := reflect.ValueOf(src)
13+
var srcValue reflect.Value
14+
15+
// *struct to struct
16+
if tempSrcValue.Type().Kind() == reflect.Pointer {
17+
if tempSrcValue.IsNil() {
18+
return nil
19+
}
20+
srcValue = tempSrcValue.Elem()
21+
} else {
22+
srcValue = tempSrcValue
23+
}
24+
25+
srcType := srcValue.Type()
26+
dst := py.NewStringDictSized(srcType.NumField())
27+
for i := 0; i < srcType.NumField(); i++ {
28+
field := srcType.Field(i)
29+
value := srcValue.Field(i).Interface()
30+
31+
keyName := field.Tag.Get("json")
32+
if len(keyName) == 0 {
33+
keyName = field.Name
34+
}
35+
36+
switch field.Type.Kind() {
37+
case reflect.Struct:
38+
fallthrough
39+
case reflect.Pointer:
40+
dst[keyName] = StructToObject(value)
41+
default:
42+
dst[keyName] = ToObject(value)
43+
}
44+
}
45+
return dst
46+
}
47+
48+
func ToObject(goVal any) py.Object {
49+
var pyObj py.Object
50+
switch val := goVal.(type) {
51+
case nil:
52+
pyObj = py.None
53+
case bool:
54+
pyObj = py.NewBool(val)
55+
case int:
56+
pyObj = py.Int(val)
57+
case int32:
58+
pyObj = py.Int(val)
59+
case int64:
60+
pyObj = py.Int(val)
61+
case float32:
62+
pyObj = py.Float(val)
63+
case float64:
64+
pyObj = py.Float(val)
65+
case string:
66+
pyObj = py.String(val)
67+
case map[string]any:
68+
pyValDict := py.NewStringDictSized(len(val))
69+
for key, value := range val {
70+
pyValDict[key] = ToObject(value)
71+
}
72+
pyObj = pyValDict
73+
default:
74+
refVal := reflect.ValueOf(goVal)
75+
switch refVal.Kind() {
76+
case reflect.Array:
77+
fallthrough
78+
case reflect.Slice:
79+
l := refVal.Len()
80+
pyValList := py.NewListWithCapacity(l)
81+
for i := 0; i < l; i++ {
82+
pyValList.Append(ToObject(refVal.Index(i).Interface()))
83+
}
84+
pyObj = pyValList
85+
case reflect.Struct:
86+
fallthrough
87+
case reflect.Pointer:
88+
pyObj = StructToObject(goVal)
89+
default:
90+
errors.NewAniErrorf("不支持的类型: %v ", reflect.ValueOf(goVal).Type()).TryPanic()
91+
}
92+
}
93+
return pyObj
94+
}
95+
96+
func ToValue(pyObj py.Object) any {
97+
var goVal any
98+
switch val := pyObj.(type) {
99+
case nil:
100+
goVal = nil
101+
case py.NoneType:
102+
goVal = nil
103+
case py.Bool:
104+
goVal = bool(val)
105+
case py.Int:
106+
goVal = int64(val)
107+
case py.Float:
108+
goVal = float64(val)
109+
case py.String:
110+
goVal = string(val)
111+
case py.StringDict:
112+
objValDict := make(map[string]any, len(val))
113+
for key, value := range val {
114+
objValDict[key] = ToValue(value)
115+
}
116+
goVal = objValDict
117+
case py.Tuple:
118+
objValList := make([]any, len(val))
119+
for i := 0; i < len(val); i++ {
120+
objValList[i] = ToValue(val[i])
121+
}
122+
goVal = objValList
123+
case *py.List:
124+
objValList := make([]any, val.Len())
125+
for i := 0; i < val.Len(); i++ {
126+
objValList[i] = ToValue(val.Items[i])
127+
}
128+
goVal = objValList
129+
case *py.Type:
130+
goVal = ToValue(val.Dict)
131+
default:
132+
errors.NewAniErrorf("不支持的类型: %v ", reflect.ValueOf(pyObj).Type()).TryPanic()
133+
}
134+
return goVal
135+
}
Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
package plugin
1+
package python_test
22

33
import (
44
"fmt"
55
"testing"
66

77
"github.com/go-python/gpython/py"
8+
9+
"github.com/wetor/AnimeGo/pkg/plugin/python"
810
)
911

1012
func TestPyObject2Object(t *testing.T) {
@@ -21,7 +23,7 @@ func TestPyObject2Object(t *testing.T) {
2123
})
2224
fmt.Println(dict)
2325

24-
obj := PyObject2Value(dict)
26+
obj := python.ToValue(dict)
2527
fmt.Println(obj)
2628
}
2729

@@ -49,6 +51,28 @@ func TestValue2PyObject(t *testing.T) {
4951
false,
5052
},
5153
}
52-
pyObj := Value2PyObject(object)
54+
pyObj := python.ToObject(object)
5355
fmt.Println(pyObj)
5456
}
57+
58+
func TestStructToObject(t *testing.T) {
59+
type InnerStruct struct {
60+
Best int `json:"in_best"`
61+
TestKey string `json:"in_test_key"`
62+
}
63+
type Struct struct {
64+
Best int `json:"best"`
65+
TestKey string `json:"test_key"`
66+
Inner InnerStruct `json:"inner"`
67+
}
68+
model := Struct{
69+
Best: 666,
70+
TestKey: "这是",
71+
Inner: InnerStruct{
72+
Best: 777,
73+
TestKey: "我",
74+
},
75+
}
76+
obj := python.ToObject(model)
77+
fmt.Println(obj)
78+
}

0 commit comments

Comments
 (0)