ip2region_private/maker/golang/cmd/edit.go

144 lines
3.6 KiB
Go

// Copyright 2022 The Ip2Region Authors. All rights reserved.
// Use of this source code is governed by a Apache2.0-style
// license that can be found in the LICENSE file.
package cmd
import (
"bufio"
"fmt"
"github.com/lionsoul2014/ip2region/maker/golang/xdb"
"os"
"regexp"
"strings"
"time"
"github.com/spf13/cobra"
)
var srcFileEdit string
// editCmd represents the edit command
var editCmd = &cobra.Command{
Use: "edit",
Short: "edit the source ip data",
Run: func(cmd *cobra.Command, args []string) {
edit()
},
}
func init() {
rootCmd.AddCommand(editCmd)
editCmd.Flags().StringVarP(&srcFileEdit, "src", "s", "", "source ip text file path (required)")
// Required flags
_ = editCmd.MarkFlagRequired("src")
}
func edit() {
rExp, err := regexp.Compile("\\s+")
if err != nil {
fmt.Printf("failed to compile regexp: %s\n", err)
return
}
fmt.Printf("init the editor from source @ `%s` ... \n", srcFileEdit)
var tStart = time.Now()
editor, err := xdb.NewEditor(srcFileEdit)
if err != nil {
fmt.Printf("failed to init editor: %s", err)
return
}
fmt.Printf("all segments loaded, length: %d, elapsed: %s\n", editor.SegLen(), time.Since(tStart))
var help = func() {
fmt.Println("command list:")
fmt.Println(" put [segment] : put the specifield $segment")
fmt.Println(" put_file [file] : put all the segments from the specified $file")
fmt.Println(" list [offset] [size] : list the first $size segments start from $offset")
fmt.Println(" save : save all the changes to the destination source file")
fmt.Println(" quit : exit the program")
fmt.Println(" help : print this help menu")
}
help()
var sTip = ""
var reader = bufio.NewReader(os.Stdin)
for {
if editor.NeedSave() {
sTip = "*"
} else {
sTip = ""
}
fmt.Printf("%seditor>> ", sTip)
line, err := reader.ReadString('\n')
if err != nil {
fmt.Printf("failed to read line from cli: %s\n", err)
break
}
cmd := strings.TrimSpace(line)
if cmd == "help" {
help()
} else if cmd == "quit" {
if editor.NeedSave() {
fmt.Printf("there are changes that need to save, type 'quit!' to force quit\n")
} else {
break
}
} else if cmd == "quit!" {
// quit directly
break
} else if cmd == "save" {
err = editor.Save()
if err != nil {
fmt.Printf("failed to save the changes: %s\n", err)
continue
}
fmt.Printf("all segments saved to %s\n", srcFileEdit)
} else if strings.HasPrefix(cmd, "list") {
var sErr error
off, size, l := 0, 10, len("list")
str := strings.TrimSpace(cmd)
if len(str) > l {
sets := rExp.Split(cmd, 3)
switch len(sets) {
case 2:
_, sErr = fmt.Sscanf(cmd, "%s %d", &str, &off)
case 3:
_, sErr = fmt.Sscanf(cmd, "%s %d %d", &str, &off, &size)
}
}
if sErr != nil {
fmt.Printf("failed to parse the offset and size: %s\n", sErr)
continue
}
fmt.Printf("+-slice(%d,%d): \n", off, size)
for _, s := range editor.Slice(off, size) {
fmt.Printf("%s\n", s)
}
} else if strings.HasPrefix(cmd, "put ") {
seg := strings.TrimSpace(cmd[len("put "):])
o, n, err := editor.Put(seg)
if err != nil {
fmt.Printf("failed to Put(%s): %s\n", seg, err)
continue
}
fmt.Printf("Put(%s): Ok, with %d deletes and %d additions\n", seg, o, n)
} else if strings.HasPrefix(cmd, "put_file ") {
file := strings.TrimSpace(cmd[len("put_file "):])
o, n, err := editor.PutFile(file)
if err != nil {
fmt.Printf("failed to PutFile(%s): %s\n", file, err)
continue
}
fmt.Printf("PutFile(%s): Ok, with %d deletes and %d additions\n", file, o, n)
} else if len(cmd) > 0 {
help()
}
}
}