diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 45f8f2b..17355eb 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -14,14 +14,14 @@ jobs: steps: - - name: Set up Go 1.13 - uses: actions/setup-go@v1 + - name: Set up Go + uses: actions/setup-go@v5 with: - go-version: 1.13 + go-version: 1.22 id: go - name: Check out code into the Go module directory - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Build run: | @@ -38,7 +38,7 @@ jobs: - name: Publish if: startsWith(github.ref, 'refs/tags/') - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: files: build/*.tar.gz env: diff --git a/cmd/cmd_util.go b/cmd/cmd_util.go index a78f1d5..8a2a786 100644 --- a/cmd/cmd_util.go +++ b/cmd/cmd_util.go @@ -41,3 +41,11 @@ func Contains(s []string, str string) bool { } return false } + +// CheckArg will check if an argument is empty and print error message +func CheckArg(arg string, name string) { + if arg == "" { + fmt.Fprintf(os.Stderr, "%s is required\n", name) + os.Exit(1) + } +} diff --git a/cmd/extract.go b/cmd/extract.go new file mode 100644 index 0000000..f5b9f37 --- /dev/null +++ b/cmd/extract.go @@ -0,0 +1,89 @@ +package cmd + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/cheggaaa/pb/v3" + "github.com/mamezou-tech/sbgraph/pkg/file" + "github.com/mamezou-tech/sbgraph/pkg/types" + "github.com/spf13/cobra" +) + +type pageSimple struct { + ID string `json:"id"` + Title string `json:"title"` + Lines []string `json:"lines"` +} + +// extractCmd represents the extract command +var extractCmd = &cobra.Command{ + Use: "extract", + Short: "Extract from downloaded JSON files", + Long: LongUsage(`Extract from downloaded JSON files that matches passed tag. + + sbgraph extract -t tagname -o outputdir`), + Run: func(cmd *cobra.Command, args []string) { + doExtract(cmd); + }, +} + +func init() { + extractCmd.PersistentFlags().StringP("tag", "t", "", "Extract pages with the specified tag.") + extractCmd.PersistentFlags().StringP("suffix", "s", "", "suffix for output directory") + rootCmd.AddCommand(extractCmd) +} + +func doExtract(cmd *cobra.Command) { + projectName := config.CurrentProject + CheckProject(projectName) + tag, _ := cmd.PersistentFlags().GetString("tag") + suffix, _ := cmd.PersistentFlags().GetString("suffix") + CheckArg(tag, "tag"); + CheckArg(suffix, "suffix"); + + fmt.Printf("Extract files : %s, tag : %s\n", projectName, tag) + var proj types.Project + err := proj.ReadFrom(projectName, config.WorkDir) + CheckErr(err) + + bar := pb.StartNew(proj.Count) + + outputDir := config.WorkDir + "/" + projectName + "-" + suffix + file.CreateDir(outputDir) + for _, idx := range proj.Pages { + var page types.Page + err := page.ReadFrom(projectName, idx.ID, config.WorkDir) + CheckErr(err) + result := containsTag(toLines(&page), tag) + if result { + var simplePage pageSimple + simplePage.ID = page.ID + simplePage.Title = page.Title + simplePage.Lines = toLines(&page) + data, _ := json.Marshal(simplePage) + err = file.WriteBytes(data, simplePage.ID+".json", outputDir) + CheckErr(err) + } + bar.Increment() + } + bar.Finish() +} + +func toLines(page *types.Page) []string { + lines := []string{} + for _, line := range page.Lines { + lines = append(lines, line.Text) + } + return lines +} + +func containsTag(lines []string, tag string) bool { + for _, line := range lines { + if strings.Contains(line, tag) { + return true + } + } + return false +} diff --git a/go.mod b/go.mod index 7baa570..c0255c0 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/mamezou-tech/sbgraph -go 1.13 +go 1.22 require ( github.com/MakeNowJust/heredoc/v2 v2.0.1 @@ -10,3 +10,26 @@ require ( github.com/spf13/cobra v0.0.6 github.com/spf13/viper v1.6.2 ) + +require ( + github.com/VividCortex/ewma v1.1.1 // indirect + github.com/fatih/color v1.7.0 // indirect + github.com/fsnotify/fsnotify v1.4.7 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/magiconair/properties v1.8.1 // indirect + github.com/mattn/go-colorable v0.1.2 // indirect + github.com/mattn/go-isatty v0.0.10 // indirect + github.com/mattn/go-runewidth v0.0.7 // indirect + github.com/mitchellh/mapstructure v1.1.2 // indirect + github.com/pelletier/go-toml v1.2.0 // indirect + github.com/spf13/afero v1.1.2 // indirect + github.com/spf13/cast v1.3.0 // indirect + github.com/spf13/jwalterweatherman v1.0.0 // indirect + github.com/spf13/pflag v1.0.3 // indirect + github.com/subosito/gotenv v1.2.0 // indirect + golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 // indirect + golang.org/x/text v0.3.0 // indirect + gopkg.in/ini.v1 v1.51.0 // indirect + gopkg.in/yaml.v2 v2.2.4 // indirect +) diff --git a/go.sum b/go.sum index 9febb93..8ccb13f 100644 --- a/go.sum +++ b/go.sum @@ -152,7 +152,6 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/pkg/types/page.go b/pkg/types/page.go index f0f6ceb..a519448 100644 --- a/pkg/types/page.go +++ b/pkg/types/page.go @@ -19,7 +19,14 @@ type Page struct { Collaborators []User `json:"collaborators"` Image string `json:"image"` Tags []string `json:"links"` - Related struct { + Lines []struct { + ID string `json:"id"` + Text string `json:"text"` + UserID string `json:"userId"` + Created int32 `json:"created"` + Updated int32 `json:"updated"` + } `json:"lines"` + Related struct { Links []struct { ID string `json:"id"` Title string `json:"title"`