feat: added modules

This commit is contained in:
Marvin Zhang
2024-06-14 15:42:50 +08:00
parent 4d0adcb6f0
commit c4d795f47f
626 changed files with 60104 additions and 0 deletions

56
core/entity/address.go Normal file
View File

@@ -0,0 +1,56 @@
package entity
import (
"errors"
"fmt"
"strings"
)
type Address struct {
Host string
Port string
}
func (a *Address) String() (res string) {
return fmt.Sprintf("%s:%s", a.Host, a.Port)
}
func (a *Address) IsEmpty() (res bool) {
return a.Host == "" || a.Port == ""
}
func (a *Address) Value() (res interface{}) {
return a
}
type AddressOptions struct {
Host string
Port string
}
func NewAddress(opts *AddressOptions) (res *Address) {
if opts == nil {
opts = &AddressOptions{}
}
//if opts.Host == "" {
// opts.Host = "localhost"
//}
if opts.Port == "" {
opts.Port = "9666"
}
return &Address{
Host: opts.Host,
Port: opts.Port,
}
}
func NewAddressFromString(address string) (res *Address, err error) {
parts := strings.Split(address, ":")
if len(parts) == 1 {
return NewAddress(&AddressOptions{Host: parts[0]}), nil
} else if len(parts) == 2 {
return NewAddress(&AddressOptions{Host: parts[0], Port: parts[1]}), nil
} else {
return nil, errors.New(fmt.Sprintf("parsing address error: %v", err))
}
}

18
core/entity/color.go Normal file
View File

@@ -0,0 +1,18 @@
package entity
type Color struct {
Name string `json:"name"`
Hex string `json:"hex"`
}
func (c *Color) GetHex() string {
return c.Hex
}
func (c *Color) GetName() string {
return c.Name
}
func (c *Color) Value() interface{} {
return c
}

17
core/entity/common.go Normal file
View File

@@ -0,0 +1,17 @@
package entity
import "strconv"
type Page struct {
Skip int
Limit int
PageNum int
PageSize int
}
func (p *Page) GetPage(pageNum string, pageSize string) {
p.PageNum, _ = strconv.Atoi(pageNum)
p.PageSize, _ = strconv.Atoi(pageSize)
p.Skip = p.PageSize * (p.PageNum - 1)
p.Limit = p.PageSize
}

View File

@@ -0,0 +1,40 @@
package entity
type ConfigSpiderData struct {
// 通用
Name string `yaml:"name" json:"name"`
DisplayName string `yaml:"display_name" json:"display_name"`
Col string `yaml:"col" json:"col"`
Remark string `yaml:"remark" json:"remark"`
Type string `yaml:"type" bson:"type"`
// 可配置爬虫
Engine string `yaml:"engine" json:"engine"`
StartUrl string `yaml:"start_url" json:"start_url"`
StartStage string `yaml:"start_stage" json:"start_stage"`
Stages []Stage `yaml:"stages" json:"stages"`
Settings map[string]string `yaml:"settings" json:"settings"`
// 自定义爬虫
Cmd string `yaml:"cmd" json:"cmd"`
}
type Stage struct {
Name string `yaml:"name" json:"name"`
IsList bool `yaml:"is_list" json:"is_list"`
ListCss string `yaml:"list_css" json:"list_css"`
ListXpath string `yaml:"list_xpath" json:"list_xpath"`
PageCss string `yaml:"page_css" json:"page_css"`
PageXpath string `yaml:"page_xpath" json:"page_xpath"`
PageAttr string `yaml:"page_attr" json:"page_attr"`
Fields []Field `yaml:"fields" json:"fields"`
}
type Field struct {
Name string `yaml:"name" json:"name"`
Css string `yaml:"css" json:"css"`
Xpath string `yaml:"xpath" json:"xpath"`
Attr string `yaml:"attr" json:"attr"`
NextStage string `yaml:"next_stage" json:"next_stage"`
Remark string `yaml:"remark" json:"remark"`
}

View File

@@ -0,0 +1,6 @@
package entity
type DataField struct {
Key string `json:"key" bson:"key"`
Type string `json:"type" bson:"type"`
}

8
core/entity/doc.go Normal file
View File

@@ -0,0 +1,8 @@
package entity
type DocItem struct {
Title string `json:"title"`
Url string `json:"url"`
Path string `json:"path"`
Children []DocItem `json:"children"`
}

54
core/entity/es.go Normal file
View File

@@ -0,0 +1,54 @@
package entity
/* ElasticsearchResponseData JSON format
{
"took" : 6,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 60,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "test_table",
"_id" : "c39ad9a2-9a37-49fb-b7ea-f1b55913e0af",
"_score" : 1.0,
"_source" : {
"_tid" : "62524ac7f5f99e7ef594de64",
"author" : "James Baldwin",
"tags" : [
"love"
],
"text" : "“Love does not begin and end the way we seem to think it does. Love is a battle, love is a war; love is a growing up.”"
}
}
]
}
}
*/
type ElasticsearchResponseData struct {
Took int64 `json:"took"`
Timeout bool `json:"timeout"`
Hits struct {
Total struct {
Value int64 `json:"value"`
Relation string `json:"relation"`
} `json:"total"`
MaxScore float64 `json:"max_score"`
Hits []struct {
Index string `json:"_index"`
Id string `json:"_id"`
Score float64 `json:"_score"`
Source interface{} `json:"_source"`
} `json:"hits"`
} `json:"hits"`
}

14
core/entity/event.go Normal file
View File

@@ -0,0 +1,14 @@
package entity
type EventData struct {
Event string
Data interface{}
}
func (d *EventData) GetEvent() string {
return d.Event
}
func (d *EventData) GetData() interface{} {
return d.Data
}

51
core/entity/export.go Normal file
View File

@@ -0,0 +1,51 @@
package entity
import (
"github.com/crawlab-team/crawlab/core/interfaces"
"time"
)
type Export struct {
Id string `json:"id"`
Type string `json:"type"`
Target string `json:"target"`
Filter interfaces.Filter `json:"filter"`
Status string `json:"status"`
StartTs time.Time `json:"start_ts"`
EndTs time.Time `json:"end_ts"`
FileName string `json:"file_name"`
DownloadPath string `json:"-"`
Limit int `json:"-"`
}
func (e *Export) GetId() string {
return e.Id
}
func (e *Export) GetType() string {
return e.Type
}
func (e *Export) GetTarget() string {
return e.Target
}
func (e *Export) GetFilter() interfaces.Filter {
return e.Filter
}
func (e *Export) GetStatus() string {
return e.Status
}
func (e *Export) GetStartTs() time.Time {
return e.StartTs
}
func (e *Export) GetEndTs() time.Time {
return e.EndTs
}
func (e *Export) GetDownloadPath() string {
return e.DownloadPath
}

68
core/entity/filter.go Normal file
View File

@@ -0,0 +1,68 @@
package entity
import (
"github.com/crawlab-team/crawlab/core/interfaces"
"reflect"
)
type Condition struct {
Key string `json:"key"`
Op string `json:"op"`
Value interface{} `json:"value"`
}
func (c *Condition) GetKey() (key string) {
return c.Key
}
func (c *Condition) SetKey(key string) {
c.Key = key
}
func (c *Condition) GetOp() (op string) {
return c.Op
}
func (c *Condition) SetOp(op string) {
c.Op = op
}
func (c *Condition) GetValue() (value interface{}) {
return c.Value
}
func (c *Condition) SetValue(value interface{}) {
c.Value = value
}
type Filter struct {
IsOr bool `form:"is_or" url:"is_or"`
Conditions []*Condition `json:"conditions"`
}
func (f *Filter) GetIsOr() (isOr bool) {
return f.IsOr
}
func (f *Filter) SetIsOr(isOr bool) {
f.IsOr = isOr
}
func (f *Filter) GetConditions() (conditions []interfaces.FilterCondition) {
for _, c := range f.Conditions {
conditions = append(conditions, c)
}
return conditions
}
func (f *Filter) SetConditions(conditions []interfaces.FilterCondition) {
f.Conditions = make([]*Condition, len(conditions))
for _, c := range conditions {
f.Conditions = append(f.Conditions, c.(*Condition))
}
}
func (f *Filter) IsNil() (ok bool) {
val := reflect.ValueOf(f)
return val.IsNil()
}

View File

@@ -0,0 +1,6 @@
package entity
type FilterSelectOption struct {
Value interface{} `json:"value" bson:"value"`
Label string `json:"label" bson:"label"`
}

View File

@@ -0,0 +1,60 @@
package entity
import (
"github.com/crawlab-team/crawlab/core/interfaces"
"os"
"time"
)
type FsFileInfo struct {
Name string `json:"name"` // file name
Path string `json:"path"` // file path
FullPath string `json:"full_path"` // file full path
Extension string `json:"extension"` // file extension
IsDir bool `json:"is_dir"` // whether it is directory
FileSize int64 `json:"file_size"` // file size (bytes)
Children []interfaces.FsFileInfo `json:"children"` // children for sub-directory
ModTime time.Time `json:"mod_time"` // modification time
Mode os.FileMode `json:"mode"` // file mode
Hash string `json:"hash"` // file hash
}
func (f *FsFileInfo) GetName() string {
return f.Name
}
func (f *FsFileInfo) GetPath() string {
return f.Path
}
func (f *FsFileInfo) GetFullPath() string {
return f.FullPath
}
func (f *FsFileInfo) GetExtension() string {
return f.Extension
}
func (f *FsFileInfo) GetIsDir() bool {
return f.IsDir
}
func (f *FsFileInfo) GetFileSize() int64 {
return f.FileSize
}
func (f *FsFileInfo) GetModTime() time.Time {
return f.ModTime
}
func (f *FsFileInfo) GetMode() os.FileMode {
return f.Mode
}
func (f *FsFileInfo) GetHash() string {
return f.Hash
}
func (f *FsFileInfo) GetChildren() []interfaces.FsFileInfo {
return f.Children
}

12
core/entity/git.go Normal file
View File

@@ -0,0 +1,12 @@
package entity
type GitPayload struct {
Paths []string `json:"paths"`
CommitMessage string `json:"commit_message"`
Branch string `json:"branch"`
Tag string `json:"tag"`
}
type GitConfig struct {
Url string `json:"url" bson:"url"`
}

View File

@@ -0,0 +1,29 @@
package entity
import (
"encoding/json"
"github.com/crawlab-team/crawlab/core/interfaces"
"github.com/crawlab-team/go-trace"
)
type GrpcBaseServiceMessage struct {
ModelId interfaces.ModelId `json:"id"`
Data []byte `json:"d"`
}
func (msg *GrpcBaseServiceMessage) GetModelId() interfaces.ModelId {
return msg.ModelId
}
func (msg *GrpcBaseServiceMessage) GetData() []byte {
return msg.Data
}
func (msg *GrpcBaseServiceMessage) ToBytes() (data []byte) {
data, err := json.Marshal(*msg)
if err != nil {
_ = trace.TraceError(err)
return data
}
return data
}

View File

@@ -0,0 +1,23 @@
package entity
import (
"github.com/crawlab-team/crawlab-db/mongo"
"github.com/crawlab-team/crawlab/core/interfaces"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type GrpcBaseServiceParams struct {
Query bson.M `json:"q"`
Id primitive.ObjectID `json:"id"`
Update bson.M `json:"u"`
Doc interfaces.Model `json:"d"`
Fields []string `json:"f"`
FindOptions *mongo.FindOptions `json:"o"`
Docs []interface{} `json:"dl"`
User interfaces.User `json:"U"`
}
func (params *GrpcBaseServiceParams) Value() interface{} {
return params
}

View File

@@ -0,0 +1,34 @@
package entity
import (
"encoding/json"
"github.com/crawlab-team/crawlab/core/interfaces"
"github.com/crawlab-team/go-trace"
)
type GrpcDelegateMessage struct {
ModelId interfaces.ModelId `json:"id"`
Method interfaces.ModelDelegateMethod `json:"m"`
Data []byte `json:"d"`
}
func (msg *GrpcDelegateMessage) GetModelId() interfaces.ModelId {
return msg.ModelId
}
func (msg *GrpcDelegateMessage) GetMethod() interfaces.ModelDelegateMethod {
return msg.Method
}
func (msg *GrpcDelegateMessage) GetData() []byte {
return msg.Data
}
func (msg *GrpcDelegateMessage) ToBytes() (data []byte) {
data, err := json.Marshal(*msg)
if err != nil {
_ = trace.TraceError(err)
return data
}
return data
}

View File

@@ -0,0 +1,8 @@
package entity
type GrpcEventServiceMessage struct {
Type string `json:"type"`
Events []string `json:"events"`
Key string `json:"key"`
Data []byte `json:"data"`
}

View File

@@ -0,0 +1,26 @@
package entity
import (
"github.com/crawlab-team/crawlab/core/interfaces"
)
type GrpcSubscribe struct {
Stream interfaces.GrpcStream
Finished chan bool
}
func (sub *GrpcSubscribe) GetStream() interfaces.GrpcStream {
return sub.Stream
}
func (sub *GrpcSubscribe) GetStreamBidirectional() interfaces.GrpcStreamBidirectional {
stream, ok := sub.Stream.(interfaces.GrpcStreamBidirectional)
if !ok {
return nil
}
return stream
}
func (sub *GrpcSubscribe) GetFinished() chan bool {
return sub.Finished
}

42
core/entity/http.go Normal file
View File

@@ -0,0 +1,42 @@
package entity
import "go.mongodb.org/mongo-driver/bson/primitive"
type Response struct {
Status string `json:"status"`
Message string `json:"message"`
Data interface{} `json:"data"`
Error string `json:"error"`
}
type ListResponse struct {
Status string `json:"status"`
Message string `json:"message"`
Total int `json:"total"`
Data interface{} `json:"data"`
Error string `json:"error"`
}
type ListRequestData struct {
PageNum int `form:"page_num" json:"page_num"`
PageSize int `form:"page_size" json:"page_size"`
SortKey string `form:"sort_key" json:"sort_key"`
Status string `form:"status" json:"status"`
Keyword string `form:"keyword" json:"keyword"`
}
type BatchRequestPayload struct {
Ids []primitive.ObjectID `form:"ids" json:"ids"`
}
type BatchRequestPayloadWithStringData struct {
Ids []primitive.ObjectID `form:"ids" json:"ids"`
Data string `form:"data" json:"data"`
Fields []string `form:"fields" json:"fields"`
}
type FileRequestPayload struct {
Path string `json:"path" form:"path"`
NewPath string `json:"new_path" form:"new_path"`
Data string `json:"data" form:"data"`
}

View File

@@ -0,0 +1,11 @@
package entity
import "github.com/crawlab-team/crawlab/core/interfaces"
type ModelDelegate struct {
Id interfaces.ModelId `json:"id"`
ColName string `json:"col_name"`
Doc interfaces.Model `json:"doc"`
Artifact interfaces.ModelArtifact `json:"a"`
User interfaces.User `json:"u"`
}

View File

@@ -0,0 +1,8 @@
package entity
import "github.com/crawlab-team/crawlab/core/interfaces"
type ModelInfo struct {
Id interfaces.ModelId
ColName string
}

17
core/entity/node.go Normal file
View File

@@ -0,0 +1,17 @@
package entity
type NodeInfo struct {
Key string `json:"key"`
IsMaster bool `json:"is_master"`
Name string `json:"name"`
Ip string `json:"ip"`
Mac string `json:"mac"`
Hostname string `json:"hostname"`
Description string `json:"description"`
AuthKey string `json:"auth_key"`
MaxRunners int `json:"max_runners"`
}
func (n NodeInfo) Value() interface{} {
return n
}

18
core/entity/pagination.go Normal file
View File

@@ -0,0 +1,18 @@
package entity
import "github.com/crawlab-team/crawlab/core/constants"
type Pagination struct {
Page int `form:"page" url:"page"`
Size int `form:"size" url:"size"`
}
func (p *Pagination) IsZero() (ok bool) {
return p.Page == 0 &&
p.Size == 0
}
func (p *Pagination) IsDefault() (ok bool) {
return p.Page == constants.PaginationDefaultPage &&
p.Size == constants.PaginationDefaultSize
}

100
core/entity/result.go Normal file
View File

@@ -0,0 +1,100 @@
package entity
import (
"encoding/json"
"github.com/crawlab-team/crawlab/core/constants"
"github.com/crawlab-team/go-trace"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type Result map[string]interface{}
func (r Result) Value() map[string]interface{} {
return r
}
func (r Result) SetValue(key string, value interface{}) {
r[key] = value
}
func (r Result) GetValue(key string) (value interface{}) {
value, _ = r[key]
return value
}
func (r Result) GetTaskId() (id primitive.ObjectID) {
_tid, ok := r[constants.TaskKey]
if !ok {
return id
}
switch _tid.(type) {
case string:
oid, err := primitive.ObjectIDFromHex(_tid.(string))
if err != nil {
return id
}
return oid
default:
return id
}
}
func (r Result) SetTaskId(id primitive.ObjectID) {
r[constants.TaskKey] = id
}
func (r Result) DenormalizeObjectId() (res Result) {
for k, v := range r {
switch v.(type) {
case primitive.ObjectID:
r[k] = v.(primitive.ObjectID).Hex()
case Result:
r[k] = v.(Result).DenormalizeObjectId()
}
}
return r
}
func (r Result) ToJSON() (res Result) {
r = r.DenormalizeObjectId()
for k, v := range r {
switch v.(type) {
case []byte:
r[k] = string(v.([]byte))
}
}
return r
}
func (r Result) Flatten() (res Result) {
r = r.ToJSON()
for k, v := range r {
switch v.(type) {
case string,
bool,
uint, uint8, uint16, uint32, uint64,
int, int8, int16, int32, int64,
float32, float64:
default:
bytes, err := json.Marshal(v)
if err != nil {
trace.PrintError(err)
return nil
}
r[k] = string(bytes)
}
}
return r
}
func (r Result) String() (s string) {
return string(r.Bytes())
}
func (r Result) Bytes() (bytes []byte) {
bytes, err := json.Marshal(r.ToJSON())
if err != nil {
return bytes
}
return bytes
}

11
core/entity/rpc.go Normal file
View File

@@ -0,0 +1,11 @@
package entity
type RpcMessage struct {
Id string `json:"id"` // 消息ID
Method string `json:"method"` // 消息方法
NodeId string `json:"node_id"` // 节点ID
Params map[string]string `json:"params"` // 参数
Timeout int `json:"timeout"` // 超时
Result string `json:"result"` // 结果
Error string `json:"error"` // 错误
}

6
core/entity/sort.go Normal file
View File

@@ -0,0 +1,6 @@
package entity
type Sort struct {
Key string `json:"key"`
Direction string `json:"d"`
}

17
core/entity/spider.go Normal file
View File

@@ -0,0 +1,17 @@
package entity
type SpiderType struct {
Type string `json:"type" bson:"_id"`
Count int `json:"count" bson:"count"`
}
type ScrapySettingParam struct {
Key string `json:"key"`
Value interface{} `json:"value"`
Type string `json:"type"`
}
type ScrapyItem struct {
Name string `json:"name"`
Fields []string `json:"fields"`
}

12
core/entity/stats.go Normal file
View File

@@ -0,0 +1,12 @@
package entity
type StatsDailyItem struct {
Date string `json:"date" bson:"_id"`
Tasks int64 `json:"tasks" bson:"tasks"`
Results int64 `json:"results" bson:"results"`
}
type StatsTasksByStatusItem struct {
Status string `json:"status" bson:"_id"`
Tasks int64 `json:"tasks" bson:"tasks"`
}

View File

@@ -0,0 +1,6 @@
package entity
type SystemInfo struct {
Edition string `json:"edition"` // edition. e.g. community / pro
Version string `json:"version"` // version. e.g. v0.6.0
}

30
core/entity/task.go Normal file
View File

@@ -0,0 +1,30 @@
package entity
import (
"encoding/json"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type TaskMessage struct {
Id primitive.ObjectID `json:"id"`
Key string `json:"key"`
Cmd string `json:"cmd"`
Param string `json:"param"`
}
func (m *TaskMessage) ToString() (string, error) {
data, err := json.Marshal(&m)
if err != nil {
return "", err
}
return string(data), err
}
type TaskRunOptions struct {
}
type StreamMessageTaskData struct {
TaskId primitive.ObjectID `json:"task_id"`
Records []Result `json:"data"`
Logs []string `json:"logs"`
}

View File

@@ -0,0 +1,11 @@
package entity
type Translation struct {
Lang string `json:"lang"`
Key string `json:"key"`
Value string `json:"value"`
}
func (t Translation) GetLang() (l string) {
return t.Lang
}

58
core/entity/ttl_map.go Normal file
View File

@@ -0,0 +1,58 @@
package entity
import (
"sync"
"time"
)
type TTLMap struct {
TTL time.Duration
data sync.Map
}
type expireEntry struct {
ExpiresAt time.Time
Value interface{}
}
func (t *TTLMap) Store(key string, val interface{}) {
t.data.Store(key, expireEntry{
ExpiresAt: time.Now().Add(t.TTL),
Value: val,
})
}
func (t *TTLMap) Load(key string) (val interface{}) {
entry, ok := t.data.Load(key)
if !ok {
return nil
}
expireEntry := entry.(expireEntry)
if expireEntry.ExpiresAt.After(time.Now()) {
return nil
}
return expireEntry.Value
}
func NewTTLMap(ttl time.Duration) (m *TTLMap) {
m = &TTLMap{
TTL: ttl,
}
go func() {
for now := range time.Tick(time.Second) {
m.data.Range(func(k, v interface{}) bool {
expiresAt := v.(expireEntry).ExpiresAt
if expiresAt.Before(now) {
m.data.Delete(k)
}
return true
})
}
}()
return
}

23
core/entity/version.go Normal file
View File

@@ -0,0 +1,23 @@
package entity
type Release struct {
Name string `json:"name"`
Draft bool `json:"draft"`
PreRelease bool `json:"pre_release"`
PublishedAt string `json:"published_at"`
Body string `json:"body"`
}
type ReleaseSlices []Release
func (r ReleaseSlices) Len() int {
return len(r)
}
func (r ReleaseSlices) Less(i, j int) bool {
return r[i].PublishedAt < r[j].PublishedAt
}
func (r ReleaseSlices) Swap(i, j int) {
r[i], r[j] = r[j], r[i]
}