diff options
| author | loyalsoldier <[email protected]> | 2021-08-27 18:27:16 +0800 |
|---|---|---|
| committer | loyalsoldier <[email protected]> | 2021-08-29 20:09:57 +0800 |
| commit | 85a343aca99d864c517f13cd3169ebcc910ec0d8 (patch) | |
| tree | eccfd3680d9dc6e22f265a9525dccac85902c2ab /plugin/plaintext/common_out.go | |
| parent | 2b32e8845d9e55b6c23ebb41bd0f382100094386 (diff) | |
Refactor: use plugin architecture to support multiple I/O formats
Diffstat (limited to 'plugin/plaintext/common_out.go')
| -rw-r--r-- | plugin/plaintext/common_out.go | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/plugin/plaintext/common_out.go b/plugin/plaintext/common_out.go new file mode 100644 index 00000000..ff4ab63b --- /dev/null +++ b/plugin/plaintext/common_out.go @@ -0,0 +1,170 @@ +package plaintext + +import ( + "bytes" + "encoding/json" + "log" + "net" + "os" + "path/filepath" + + "github.com/Loyalsoldier/geoip/lib" +) + +var ( + defaultOutputDirForTextOut = filepath.Join("./", "output", "text") + defaultOutputDirForClashRuleSetClassicalOut = filepath.Join("./", "output", "clash", "classical") + defaultOutputDirForClashRuleSetIPCIDROut = filepath.Join("./", "output", "clash", "ipcidr") + defaultOutputDirForSurgeRuleSetOut = filepath.Join("./", "output", "surge") +) + +type textOut struct { + Type string + Action lib.Action + Description string + OutputDir string + Want []string + OnlyIPType lib.IPType +} + +func newTextOut(iType string, action lib.Action, data json.RawMessage) (lib.OutputConverter, error) { + var tmp struct { + OutputDir string `json:"outputDir"` + Want []string `json:"wantedList"` + OnlyIPType lib.IPType `json:"onlyIPType"` + } + + if len(data) > 0 { + if err := json.Unmarshal(data, &tmp); err != nil { + return nil, err + } + } + + if tmp.OutputDir == "" { + switch iType { + case typeTextOut: + tmp.OutputDir = defaultOutputDirForTextOut + case typeClashRuleSetClassicalOut: + tmp.OutputDir = defaultOutputDirForClashRuleSetClassicalOut + case typeClashRuleSetIPCIDROut: + tmp.OutputDir = defaultOutputDirForClashRuleSetIPCIDROut + case typeSurgeRuleSetOut: + tmp.OutputDir = defaultOutputDirForSurgeRuleSetOut + } + } + + return &textOut{ + Type: iType, + Action: action, + Description: descTextOut, + OutputDir: tmp.OutputDir, + Want: tmp.Want, + OnlyIPType: tmp.OnlyIPType, + }, nil +} + +func (t *textOut) marshalBytes(entry *lib.Entry) ([]byte, error) { + var err error + + var entryCidr []string + switch t.OnlyIPType { + case lib.IPv4: + entryCidr, err = entry.MarshalText(lib.IgnoreIPv6) + case lib.IPv6: + entryCidr, err = entry.MarshalText(lib.IgnoreIPv4) + default: + entryCidr, err = entry.MarshalText() + } + if err != nil { + return nil, err + } + + var buf bytes.Buffer + switch t.Type { + case typeTextOut: + err = t.marshalBytesForTextOut(&buf, entryCidr) + case typeClashRuleSetClassicalOut: + err = t.marshalBytesForClashRuleSetClassicalOut(&buf, entryCidr) + case typeClashRuleSetIPCIDROut: + err = t.marshalBytesForClashRuleSetIPCIDROut(&buf, entryCidr) + case typeSurgeRuleSetOut: + err = t.marshalBytesForSurgeRuleSetOut(&buf, entryCidr) + default: + return nil, lib.ErrNotSupportedFormat + } + if err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (t *textOut) marshalBytesForTextOut(buf *bytes.Buffer, entryCidr []string) error { + for _, cidr := range entryCidr { + buf.WriteString(cidr) + buf.WriteString("\n") + } + return nil +} + +func (t *textOut) marshalBytesForClashRuleSetClassicalOut(buf *bytes.Buffer, entryCidr []string) error { + buf.WriteString("payload:\n") + for _, cidr := range entryCidr { + ip, _, err := net.ParseCIDR(cidr) + if err != nil { + return err + } + if ip.To4() != nil { + buf.WriteString(" - IP-CIDR,") + } else { + buf.WriteString(" - IP-CIDR6,") + } + buf.WriteString(cidr) + buf.WriteString("\n") + } + + return nil +} + +func (t *textOut) marshalBytesForClashRuleSetIPCIDROut(buf *bytes.Buffer, entryCidr []string) error { + buf.WriteString("payload:\n") + for _, cidr := range entryCidr { + buf.WriteString(" - '") + buf.WriteString(cidr) + buf.WriteString("'\n") + } + + return nil +} + +func (t *textOut) marshalBytesForSurgeRuleSetOut(buf *bytes.Buffer, entryCidr []string) error { + for _, cidr := range entryCidr { + ip, _, err := net.ParseCIDR(cidr) + if err != nil { + return err + } + if ip.To4() != nil { + buf.WriteString("IP-CIDR,") + } else { + buf.WriteString("IP-CIDR6,") + } + buf.WriteString(cidr) + buf.WriteString("\n") + } + + return nil +} + +func (t *textOut) writeFile(filename string, data []byte) error { + if err := os.MkdirAll(t.OutputDir, 0755); err != nil { + return err + } + + if err := os.WriteFile(filepath.Join(t.OutputDir, filename), data, 0644); err != nil { + return err + } + + log.Printf("✅ [%s] %s --> %s", t.Type, filename, t.OutputDir) + + return nil +} |
